1{ config, pkgs, lib, ... }:
2
3with lib;
4
5let
6 cfg = config.hardware.openrazer;
7 kernelPackages = config.boot.kernelPackages;
8
9 toPyBoolStr = b: if b then "True" else "False";
10
11 daemonExe = "${pkgs.openrazer-daemon}/bin/openrazer-daemon --config ${daemonConfFile}";
12
13 daemonConfFile = pkgs.writeTextFile {
14 name = "razer.conf";
15 text = ''
16 [General]
17 verbose_logging = ${toPyBoolStr cfg.verboseLogging}
18
19 [Startup]
20 sync_effects_enabled = ${toPyBoolStr cfg.syncEffectsEnabled}
21 devices_off_on_screensaver = ${toPyBoolStr cfg.devicesOffOnScreensaver}
22 mouse_battery_notifier = ${toPyBoolStr cfg.mouseBatteryNotifier}
23
24 [Statistics]
25 key_statistics = ${toPyBoolStr cfg.keyStatistics}
26 '';
27 };
28
29 dbusServiceFile = pkgs.writeTextFile rec {
30 name = "org.razer.service";
31 destination = "/share/dbus-1/services/${name}";
32 text = ''
33 [D-BUS Service]
34 Name=org.razer
35 Exec=${daemonExe}
36 SystemdService=openrazer-daemon.service
37 '';
38 };
39
40 drivers = [
41 "razerkbd"
42 "razermouse"
43 "razerfirefly"
44 "razerkraken"
45 "razermug"
46 "razercore"
47 ];
48in
49{
50 options = {
51 hardware.openrazer = {
52 enable = mkEnableOption "OpenRazer drivers and userspace daemon";
53
54 verboseLogging = mkOption {
55 type = types.bool;
56 default = false;
57 description = ''
58 Whether to enable verbose logging. Logs debug messages.
59 '';
60 };
61
62 syncEffectsEnabled = mkOption {
63 type = types.bool;
64 default = true;
65 description = ''
66 Set the sync effects flag to true so any assignment of
67 effects will work across devices.
68 '';
69 };
70
71 devicesOffOnScreensaver = mkOption {
72 type = types.bool;
73 default = true;
74 description = ''
75 Turn off the devices when the systems screensaver kicks in.
76 '';
77 };
78
79 mouseBatteryNotifier = mkOption {
80 type = types.bool;
81 default = true;
82 description = ''
83 Mouse battery notifier.
84 '';
85 };
86
87 keyStatistics = mkOption {
88 type = types.bool;
89 default = false;
90 description = ''
91 Collects number of keypresses per hour per key used to
92 generate a heatmap.
93 '';
94 };
95 };
96 };
97
98 config = mkIf cfg.enable {
99 boot.extraModulePackages = [ kernelPackages.openrazer ];
100 boot.kernelModules = drivers;
101
102 # Makes the man pages available so you can succesfully run
103 # > systemctl --user help openrazer-daemon
104 environment.systemPackages = [ pkgs.python3Packages.openrazer-daemon.man ];
105
106 services.udev.packages = [ kernelPackages.openrazer ];
107 services.dbus.packages = [ dbusServiceFile ];
108
109 # A user must be a member of the plugdev group in order to start
110 # the openrazer-daemon. Therefore we make sure that the plugdev
111 # group exists.
112 users.groups.plugdev = {};
113
114 systemd.user.services.openrazer-daemon = {
115 description = "Daemon to manage razer devices in userspace";
116 unitConfig.Documentation = "man:openrazer-daemon(8)";
117 # Requires a graphical session so the daemon knows when the screensaver
118 # starts. See the 'devicesOffOnScreensaver' option.
119 wantedBy = [ "graphical-session.target" ];
120 partOf = [ "graphical-session.target" ];
121 serviceConfig = {
122 Type = "dbus";
123 BusName = "org.razer";
124 ExecStart = "${daemonExe} --foreground";
125 Restart = "always";
126 };
127 };
128 };
129
130 meta = {
131 maintainers = with lib.maintainers; [ roelvandijk ];
132 };
133}