at 25.11-pre 4.5 kB view raw
1{ 2 config, 3 pkgs, 4 lib, 5 ... 6}: 7 8with lib; 9 10let 11 cfg = config.services.clight; 12 13 toConf = 14 v: 15 if builtins.isFloat v then 16 toString v 17 else if isInt v then 18 toString v 19 else if isBool v then 20 boolToString v 21 else if isString v then 22 ''"${escape [ ''"'' ] v}"'' 23 else if isList v then 24 "[ " + concatMapStringsSep ", " toConf v + " ]" 25 else if isAttrs v then 26 "\n{\n" + convertAttrs v + "\n}" 27 else 28 abort "clight.toConf: unexpected type (v = ${v})"; 29 30 getSep = v: if isAttrs v then ":" else "="; 31 32 convertAttrs = 33 attrs: 34 concatStringsSep "\n" ( 35 mapAttrsToList (name: value: "${toString name} ${getSep value} ${toConf value};") attrs 36 ); 37 38 clightConf = pkgs.writeText "clight.conf" ( 39 convertAttrs (filterAttrs (_: value: value != null) cfg.settings) 40 ); 41in 42{ 43 options.services.clight = { 44 enable = mkEnableOption "clight"; 45 46 temperature = { 47 day = mkOption { 48 type = types.int; 49 default = 5500; 50 description = '' 51 Colour temperature to use during the day, between 52 `1000` and `25000` K. 53 ''; 54 }; 55 night = mkOption { 56 type = types.int; 57 default = 3700; 58 description = '' 59 Colour temperature to use at night, between 60 `1000` and `25000` K. 61 ''; 62 }; 63 }; 64 65 settings = 66 let 67 validConfigTypes = 68 with types; 69 oneOf [ 70 int 71 str 72 bool 73 float 74 ]; 75 collectionTypes = 76 with types; 77 oneOf [ 78 validConfigTypes 79 (listOf validConfigTypes) 80 ]; 81 in 82 mkOption { 83 type = with types; attrsOf (nullOr (either collectionTypes (attrsOf collectionTypes))); 84 default = { }; 85 example = { 86 captures = 20; 87 gamma_long_transition = true; 88 ac_capture_timeouts = [ 89 120 90 300 91 60 92 ]; 93 }; 94 description = '' 95 Additional configuration to extend clight.conf. See 96 <https://github.com/FedeDP/Clight/blob/master/Extra/clight.conf> for a 97 sample configuration file. 98 ''; 99 }; 100 }; 101 102 config = mkIf cfg.enable { 103 assertions = 104 let 105 inRange = 106 v: l: r: 107 v >= l && v <= r; 108 in 109 [ 110 { 111 assertion = 112 config.location.provider == "manual" 113 -> inRange config.location.latitude (-90) 90 && inRange config.location.longitude (-180) 180; 114 message = "You must specify a valid latitude and longitude if manually providing location"; 115 } 116 ]; 117 118 boot.kernelModules = [ "i2c_dev" ]; 119 environment.systemPackages = with pkgs; [ 120 clight 121 clightd 122 ]; 123 services.dbus.packages = with pkgs; [ 124 clight 125 clightd 126 ]; 127 services.upower.enable = true; 128 129 services.clight.settings = 130 { 131 gamma.temp = 132 with cfg.temperature; 133 mkDefault [ 134 day 135 night 136 ]; 137 } 138 // (optionalAttrs (config.location.provider == "manual") { 139 daytime.latitude = mkDefault config.location.latitude; 140 daytime.longitude = mkDefault config.location.longitude; 141 }); 142 143 services.geoclue2.appConfig.clightc = { 144 isAllowed = true; 145 isSystem = true; 146 }; 147 148 systemd.services.clightd = { 149 requires = [ "polkit.service" ]; 150 wantedBy = [ "multi-user.target" ]; 151 152 description = "Bus service to manage various screen related properties (gamma, dpms, backlight)"; 153 serviceConfig = { 154 Type = "dbus"; 155 BusName = "org.clightd.clightd"; 156 Restart = "on-failure"; 157 RestartSec = 5; 158 ExecStart = '' 159 ${pkgs.clightd}/bin/clightd 160 ''; 161 }; 162 }; 163 164 systemd.user.services.clight = { 165 after = [ 166 "upower.service" 167 "clightd.service" 168 ]; 169 wants = [ 170 "upower.service" 171 "clightd.service" 172 ]; 173 partOf = [ "graphical-session.target" ]; 174 wantedBy = [ "graphical-session.target" ]; 175 176 description = "C daemon to adjust screen brightness to match ambient brightness, as computed capturing frames from webcam"; 177 serviceConfig = { 178 Restart = "on-failure"; 179 RestartSec = 5; 180 ExecStart = '' 181 ${pkgs.clight}/bin/clight --conf-file ${clightConf} 182 ''; 183 }; 184 }; 185 }; 186}