1 { config, lib, pkgs, ... }:
3 cfg = config.services.zigbee2mqtt;
5 format = pkgs.formats.yaml { };
6 configFile = format.generate "zigbee2mqtt.yaml" cfg.settings;
10 meta.maintainers = with lib.maintainers; [ sweber hexa ];
13 # Remove warning before the 21.11 release
14 (lib.mkRenamedOptionModule [ "services" "zigbee2mqtt" "config" ] [ "services" "zigbee2mqtt" "settings" ])
17 options.services.zigbee2mqtt = {
18 enable = lib.mkEnableOption "zigbee2mqtt service";
20 package = lib.mkPackageOption pkgs "zigbee2mqtt" { };
22 dataDir = lib.mkOption {
23 description = "Zigbee2mqtt data directory";
24 default = "/var/lib/zigbee2mqtt";
25 type = lib.types.path;
28 settings = lib.mkOption {
31 example = lib.literalExpression ''
33 homeassistant = config.services.home-assistant.enable;
36 port = "/dev/ttyACM1";
41 Your {file}`configuration.yaml` as a Nix attribute set.
42 Check the [documentation](https://www.zigbee2mqtt.io/information/configuration.html)
48 config = lib.mkIf (cfg.enable) {
50 # preset config values
51 services.zigbee2mqtt.settings = {
52 homeassistant = lib.mkDefault config.services.home-assistant.enable;
53 permit_join = lib.mkDefault false;
55 base_topic = lib.mkDefault "zigbee2mqtt";
56 server = lib.mkDefault "mqtt://localhost:1883";
58 serial.port = lib.mkDefault "/dev/ttyACM0";
59 # reference device/group configuration, that is kept in a separate file
60 # to prevent it being overwritten in the units ExecStartPre script
61 devices = lib.mkDefault "devices.yaml";
62 groups = lib.mkDefault "groups.yaml";
65 systemd.services.zigbee2mqtt = {
66 description = "Zigbee2mqtt Service";
67 wantedBy = [ "multi-user.target" ];
68 after = [ "network.target" ];
69 environment.ZIGBEE2MQTT_DATA = cfg.dataDir;
71 ExecStart = "${cfg.package}/bin/zigbee2mqtt";
73 Group = "zigbee2mqtt";
74 WorkingDirectory = cfg.dataDir;
75 Restart = "on-failure";
78 CapabilityBoundingSet = "";
79 DeviceAllow = lib.optionals (lib.hasPrefix "/" cfg.settings.serial.port) [ cfg.settings.serial.port ];
80 DevicePolicy = "closed";
81 LockPersonality = true;
82 MemoryDenyWriteExecute = false;
83 NoNewPrivileges = true;
84 PrivateDevices = false; # prevents access to /dev/serial, because it is set 0700 root:root
88 ProtectControlGroups = true;
90 ProtectHostname = true;
91 ProtectKernelLogs = true;
92 ProtectKernelModules = true;
93 ProtectKernelTunables = true;
94 ProtectProc = "invisible";
96 ProtectSystem = "strict";
97 ReadWritePaths = cfg.dataDir;
99 RestrictAddressFamilies = [
103 RestrictNamespaces = true;
104 RestrictRealtime = true;
105 RestrictSUIDSGID = true;
106 SupplementaryGroups = [
109 SystemCallArchitectures = "native";
111 "@system-service @pkey"
112 "~@privileged @resources"
117 cp --no-preserve=mode ${configFile} "${cfg.dataDir}/configuration.yaml"
121 users.users.zigbee2mqtt = {
124 group = "zigbee2mqtt";
125 uid = config.ids.uids.zigbee2mqtt;
128 users.groups.zigbee2mqtt.gid = config.ids.gids.zigbee2mqtt;