1{ lib
2, pkgs
3, config
4, ...
5}:
6
7with lib;
8
9let
10 cfg = config.services.evcc;
11
12 format = pkgs.formats.yaml {};
13 configFile = format.generate "evcc.yml" cfg.settings;
14
15 package = pkgs.evcc;
16in
17
18{
19 meta.maintainers = with lib.maintainers; [ hexa ];
20
21 options.services.evcc = with types; {
22 enable = mkEnableOption (lib.mdDoc "EVCC, the extensible EV Charge Controller with PV integration");
23
24 extraArgs = mkOption {
25 type = listOf str;
26 default = [];
27 description = lib.mdDoc ''
28 Extra arguments to pass to the evcc executable.
29 '';
30 };
31
32 settings = mkOption {
33 type = format.type;
34 description = lib.mdDoc ''
35 evcc configuration as a Nix attribute set.
36
37 Check for possible options in the sample [evcc.dist.yaml](https://github.com/andig/evcc/blob/${package.version}/evcc.dist.yaml].
38 '';
39 };
40 };
41
42 config = mkIf cfg.enable {
43 systemd.services.evcc = {
44 after = [
45 "network-online.target"
46 "mosquitto.target"
47 ];
48 wantedBy = [
49 "multi-user.target"
50 ];
51 environment.HOME = "/var/lib/evcc";
52 path = with pkgs; [
53 glibc # requires getent
54 ];
55 serviceConfig = {
56 ExecStart = "${package}/bin/evcc --config ${configFile} ${escapeShellArgs cfg.extraArgs}";
57 CapabilityBoundingSet = [ "" ];
58 DeviceAllow = [
59 "char-ttyUSB"
60 ];
61 DevicePolicy = "closed";
62 DynamicUser = true;
63 LockPersonality = true;
64 MemoryDenyWriteExecute = true;
65 RestrictAddressFamilies = [
66 "AF_INET"
67 "AF_INET6"
68 "AF_UNIX"
69 ];
70 RestrictNamespaces = true;
71 RestrictRealtime = true;
72 PrivateTmp = true;
73 PrivateUsers = true;
74 ProcSubset = "pid";
75 ProtectClock = true;
76 ProtectControlGroups= true;
77 ProtectHome = true;
78 ProtectHostname = true;
79 ProtectKernelLogs = true;
80 ProtectKernelModules = true;
81 ProtectKernelTunables = true;
82 ProtectProc = "invisible";
83 StateDirectory = "evcc";
84 SystemCallArchitectures = "native";
85 SystemCallFilter = [
86 "@system-service"
87 "~@privileged"
88 ];
89 UMask = "0077";
90 User = "evcc";
91 };
92 };
93 };
94
95 meta.buildDocsInSandbox = false;
96}