1 { config, lib, pkgs, ... }:
6 cfg = config.services.zigbee2mqtt;
8 format = pkgs.formats.yaml { };
9 configFile = format.generate "zigbee2mqtt.yaml" cfg.settings;
13 meta.maintainers = with maintainers; [ sweber hexa ];
16 # Remove warning before the 21.11 release
17 (mkRenamedOptionModule [ "services" "zigbee2mqtt" "config" ] [ "services" "zigbee2mqtt" "settings" ])
20 options.services.zigbee2mqtt = {
21 enable = mkEnableOption (lib.mdDoc "zigbee2mqtt service");
24 description = lib.mdDoc "Zigbee2mqtt package to use";
25 default = pkgs.zigbee2mqtt;
26 defaultText = literalExpression ''
33 description = lib.mdDoc "Zigbee2mqtt data directory";
34 default = "/var/lib/zigbee2mqtt";
41 example = literalExpression ''
43 homeassistant = config.services.home-assistant.enable;
46 port = "/dev/ttyACM1";
50 description = lib.mdDoc ''
51 Your {file}`configuration.yaml` as a Nix attribute set.
52 Check the [documentation](https://www.zigbee2mqtt.io/information/configuration.html)
58 config = mkIf (cfg.enable) {
60 # preset config values
61 services.zigbee2mqtt.settings = {
62 homeassistant = mkDefault config.services.home-assistant.enable;
63 permit_join = mkDefault false;
65 base_topic = mkDefault "zigbee2mqtt";
66 server = mkDefault "mqtt://localhost:1883";
68 serial.port = mkDefault "/dev/ttyACM0";
69 # reference device/group configuration, that is kept in a separate file
70 # to prevent it being overwritten in the units ExecStartPre script
71 devices = mkDefault "devices.yaml";
72 groups = mkDefault "groups.yaml";
75 systemd.services.zigbee2mqtt = {
76 description = "Zigbee2mqtt Service";
77 wantedBy = [ "multi-user.target" ];
78 after = [ "network.target" ];
79 environment.ZIGBEE2MQTT_DATA = cfg.dataDir;
81 ExecStart = "${cfg.package}/bin/zigbee2mqtt";
83 Group = "zigbee2mqtt";
84 WorkingDirectory = cfg.dataDir;
85 Restart = "on-failure";
88 CapabilityBoundingSet = "";
90 config.services.zigbee2mqtt.settings.serial.port
92 DevicePolicy = "closed";
93 LockPersonality = true;
94 MemoryDenyWriteExecute = false;
95 NoNewPrivileges = true;
96 PrivateDevices = false; # prevents access to /dev/serial, because it is set 0700 root:root
100 ProtectControlGroups = true;
102 ProtectHostname = true;
103 ProtectKernelLogs = true;
104 ProtectKernelModules = true;
105 ProtectKernelTunables = true;
106 ProtectProc = "invisible";
108 ProtectSystem = "strict";
109 ReadWritePaths = cfg.dataDir;
111 RestrictAddressFamilies = [
115 RestrictNamespaces = true;
116 RestrictRealtime = true;
117 RestrictSUIDSGID = true;
118 SupplementaryGroups = [
121 SystemCallArchitectures = "native";
123 "@system-service @pkey"
124 "~@privileged @resources"
129 cp --no-preserve=mode ${configFile} "${cfg.dataDir}/configuration.yaml"
133 users.users.zigbee2mqtt = {
136 group = "zigbee2mqtt";
137 uid = config.ids.uids.zigbee2mqtt;
140 users.groups.zigbee2mqtt.gid = config.ids.gids.zigbee2mqtt;