{
	config,
	container,
	lib,
	...
}: let
	cfg = config.container.module.iot;
in {
	options.container.module.iot = {
		enable = lib.mkEnableOption "IoT service.";
		address = lib.mkOption {
			default = "10.1.0.27";
			type    = lib.types.str;
		};
		port = lib.mkOption {
			default = 8123;
			type    = lib.types.int;
		};
		domain = lib.mkOption {
			default = "iot.${config.container.domain}";
			type    = lib.types.str;
		};
		storage = lib.mkOption {
			default = "${config.container.storage}/iot";
			type    = lib.types.str;
		};
	};

	config = lib.mkIf cfg.enable {
		systemd.tmpfiles.rules = container.mkContainerDir cfg [
			"data"
		];

		containers.iot = container.mkContainer cfg {
			bindMounts = {
				"/var/lib/hass" = {
					hostPath   = "${cfg.storage}/data";
					isReadOnly = false;
				};
				"/dev/ttyACM0" = {
					hostPath   = "/dev/ttyACM0";
					isReadOnly = false;
				};
				"/dev/serial/by-id" = {
					hostPath   = "/dev/serial/by-id";
					isReadOnly = false;
				};
			}
			// container.attachMedia "photo" true
			;

			allowedDevices = [
				{
					modifier = "rwm";
					node     = "/dev/ttyACM0";
				}
			];

			config = { ... }: container.mkContainerConfig cfg {
				# Allow Hass to talk to Zigbee dongle.
				users.users.hass.extraGroups = [
					"dialout"
					"tty"
				];

				services.home-assistant = {
					# NOTE: Missing: hacs. Inside hacs: `card-mod`, `Clock Weather Card`, `WallPanel` and `Yandex.Station`.
					enable = true;
					# NOTE: Using imperative config because of secrets.
					config = null;
					configDir = "/var/lib/hass";
					extraComponents = [
						"caldav"
						"met"
						"sun"
						"systemmonitor"
						"zha"
					];
					extraPackages =
						python3Packages: with python3Packages; [
							aiodhcpwatcher
							aiodiscover
							aiogithubapi
							arrow
							async-upnp-client
							av
							gtts
							ha-ffmpeg
							hassil
							home-assistant-intents
							mutagen
							numpy
							pymicro-vad
							pynacl
							pyspeex-noise
							python-telegram-bot
							pyturbojpeg
							zeroconf
						];
					# lovelaceConfig = {
					#   title = "Home IoT control center.";
					# };
				};

				# HACK: Delay so that nextcloud calendar can reply on reboot.
				systemd = {
					services."home-assistant".wantedBy = lib.mkForce [ ];
					timers.fixsystemd = {
						timerConfig = {
							OnBootSec = 60;
							Unit = "home-assistant.service";
						};
						wantedBy = [ "timers.target" ];
					};
				};
			};
		};
	};
}