{ config, lib, pkgs, ... }: with lib; let cfg = config.services.homeAssistantConfig; in { options.services.homeAssistantConfig = mkOption { default = null; type = with types; nullOr (submodule { options = { group = mkOption { default = null; example = { schlafzimmer = { view = false; entities = [ "switch.pal01" ]; }; }; type = with types; nullOr (attrsOf ( submodule { options = { name = mkOption { default = null; type = with types; nullOr str; description = '' (string)(Optional)Name of the group. ''; }; view = mkOption { default = false; type = with types; bool; description = '' (boolean)(Optional)If yes then the entry will be shown as a view (tab) at the top. Groups that are set to view: true cannot be used as entities in other views. ''; }; icon = mkOption { default = null; type = with types; nullOr str; description = '' (string)(Optional)If the group is a view, this icon will show at the top in the frontend instead of the name. If the group is a view and both name and icon have been specified, the icon will appear at the top of the frontend and the name will be displayed as the mouse-over text. If it’s not a view, then the icon shows when this group is used in another group. ''; }; control = mkOption { default = null; type = with types; nullOr str; description = '' (string)(Optional)Set value to hidden. If hidden then the group switch will be hidden. ''; }; entities = mkOption { type = with types; listOf str; description = '' (list)(Required)Array or comma delimited string, list of entities to group. ''; }; all = mkOption { default = true; type = with types; bool; description = '' (boolean)(Optional)Set this to true if the group state should only turn on if all grouped entities are on. ''; }; }; })); }; homeassistant = mkOption { type = with types; (submodule { options = { name = mkOption { default = "Home"; type = with types; str; }; time_zone = mkOption { default = config.time.timeZone; type = with types; str; }; latitude = mkOption { default = 52.464031; type = with types; float; }; longitude = mkOption { default = 13.381925; type = with types; float; }; elevation = mkOption { default = 34; type = with types; int; }; unit_system = mkOption { default = "metric"; type = with types; str; }; whitelist_external_dirs = mkOption { default = null; type = with types; nullOr (listOf str); }; auth_providers = mkOption { default = null; type = with types; nullOr (listOf attrs); }; customize = mkOption { type = with types; attrsOf (submodule{ options = { friendly_name = mkOption { type = with types; str; }; entity_picture = mkOption { default = null; type = with types; nullOr str; }; icon = mkOption { default = null; type = with types; nullOr str; }; };}); }; };}); }; introduction = mkOption { default = {}; type = with types; attrs; }; frontend = mkOption { default = {}; type = with types; attrs; }; config = mkOption { default = {}; type = with types; attrs; }; http = mkOption { default = null; type = with types; nullOr attrs; }; discovery = mkOption { default = null; type = with types; nullOr attrs; }; history = mkOption { default = null; type = with types; nullOr attrs; }; logbook = mkOption { default = null; type = with types; nullOr attrs; }; logger = mkOption { default = {}; type = with types; attrs; }; lovelace = mkOption { default = { mode = "yaml"; }; type = with types; nullOr attrs; }; map = mkOption { default = null; type = with types; nullOr attrs; }; mqtt = mkOption { default = null; type = with types; nullOr attrs; }; sun = mkOption { default = null; type = with types; nullOr attrs; }; switch = mkOption { default = null; type = with types; nullOr (listOf attrs); }; binary_sensor = mkOption { default = null; type = with types; nullOr (listOf attrs); }; sensor = mkOption { default = null; type = with types; nullOr (listOf attrs); }; prometheus = mkOption { default = null; type = with types; nullOr attrs; }; automation = mkOption { default = null; type = with types; nullOr (listOf attrs); }; media_player = mkOption { default = null; type = with types; nullOr (listOf attrs); }; mysensors = mkOption { default = null; type = with types; nullOr attrs; }; script = mkOption { default = null; type = with types; nullOr (attrsOf (submodule { options = { alias = mkOption { default = null; type = with types; nullOr str; }; sequence = mkOption { default = []; type = with types; listOf attrs; }; }; })); }; input_number = mkOption { default = null; type = with types; nullOr (attrsOf attrs); }; input_text = mkOption { default = null; type = with types; nullOr (attrsOf attrs); }; input_select = mkOption { default = null; type = with types; nullOr (attrsOf attrs); }; input_boolean = mkOption { default = null; type = with types; (attrsOf attrs); }; input_datetime = mkOption { default = null; type = with types; (attrsOf attrs); }; calendar = mkOption { default = []; type = with types; listOf attrs; }; shell_command = mkOption { default = null; type = with types; nullOr (attrsOf str); }; };}); description = '' home-assistant configuration ''; }; config = mkIf (cfg != null) { services.home-assistant.config = let sanitize = configuration: lib.getAttr (builtins.typeOf configuration) { bool = configuration; int = configuration; string = configuration; str = configuration; float = configuration; list = map sanitize configuration; set = let stripped = lib.flip lib.filterAttrs configuration (name: value: name != "_module" && name != "_ref" && value != null ); recursiveSanitized = lib.mapAttrs (lib.const sanitize) stripped; in if ( length ( attrNames configuration ) == 0 ) then null else recursiveSanitized; }; in sanitize cfg ; }; }