Added teslamate configuration
This commit is contained in:
		
							parent
							
								
									00319bf5ee
								
							
						
					
					
						commit
						478198d88e
					
				
					 13 changed files with 253 additions and 3 deletions
				
			
		| 
						 | 
				
			
			@ -21,6 +21,13 @@ in {
 | 
			
		|||
    };
 | 
			
		||||
  };
 | 
			
		||||
  config = mkIf cfg.enable {
 | 
			
		||||
    age.secrets = {
 | 
			
		||||
      teslamate_db_for_grafana = {
 | 
			
		||||
        file = ../../../../secrets/teslamate_db.age;
 | 
			
		||||
        owner = "grafana";
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    services.grafana = {
 | 
			
		||||
      enable = true;
 | 
			
		||||
      settings.server = {
 | 
			
		||||
| 
						 | 
				
			
			@ -47,6 +54,49 @@ in {
 | 
			
		|||
              access = "proxy";
 | 
			
		||||
              url = "http://127.0.0.1:${toString config.services.loki.configuration.server.http_listen_port}";
 | 
			
		||||
            }
 | 
			
		||||
            {
 | 
			
		||||
              name = "TeslaMate";
 | 
			
		||||
              type = "postgres";
 | 
			
		||||
              access = "proxy";
 | 
			
		||||
              url = "localhost:5432";
 | 
			
		||||
              user = "teslamate";
 | 
			
		||||
              database = "teslamate";
 | 
			
		||||
              secureJsonData = {
 | 
			
		||||
                password = "$__file{${config.age.secrets.teslamate_db_for_grafana.path}}";
 | 
			
		||||
              };
 | 
			
		||||
              jsonData = {
 | 
			
		||||
                # TODO: Automate this somehow?
 | 
			
		||||
                postgresVersion = "1400";
 | 
			
		||||
                sslmode = "disable";
 | 
			
		||||
              };
 | 
			
		||||
            }
 | 
			
		||||
          ];
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        dashboards = {
 | 
			
		||||
          settings.providers = [
 | 
			
		||||
            {
 | 
			
		||||
              name = "teslamate";
 | 
			
		||||
              orgId = 1;
 | 
			
		||||
              folder = "TeslaMate";
 | 
			
		||||
              folderUid = "Nr4ofiDZk";
 | 
			
		||||
              type = "file";
 | 
			
		||||
              disableDeletion = false;
 | 
			
		||||
              editable = true;
 | 
			
		||||
              updateIntervalSeconds = 86400;
 | 
			
		||||
              options.path = "${pkgs.aa.teslamate-grafana-dashboards}/dashboards";
 | 
			
		||||
            }
 | 
			
		||||
            {
 | 
			
		||||
              name = "teslamate_internal";
 | 
			
		||||
              orgId = 1;
 | 
			
		||||
              folder = "TeslaMate/Internal";
 | 
			
		||||
              folderUid = "Nr5ofiDZk";
 | 
			
		||||
              type = "file";
 | 
			
		||||
              disableDeletion = false;
 | 
			
		||||
              editable = true;
 | 
			
		||||
              updateIntervalSeconds = 86400;
 | 
			
		||||
              options.path = "${pkgs.aa.teslamate-grafana-dashboards}/dashboards/internal";
 | 
			
		||||
            }
 | 
			
		||||
          ];
 | 
			
		||||
        };
 | 
			
		||||
      };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,6 +17,7 @@ in {
 | 
			
		|||
    age.secrets = {
 | 
			
		||||
      hass_mqtt.file = ../../../../secrets/hass_mqtt.age;
 | 
			
		||||
      theengs_ble_mqtt.file = ../../../../secrets/theengs_ble_mqtt.age;
 | 
			
		||||
      teslamate_mqtt.file = ../../../../secrets/teslamate_mqtt.age;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    services.mosquitto = {
 | 
			
		||||
| 
						 | 
				
			
			@ -28,6 +29,7 @@ in {
 | 
			
		|||
              acl = [
 | 
			
		||||
                "readwrite home/#"
 | 
			
		||||
                "readwrite homeassistant/#"
 | 
			
		||||
                "read teslamate/#"
 | 
			
		||||
              ];
 | 
			
		||||
              passwordFile = config.age.secrets.hass_mqtt.path;
 | 
			
		||||
            };
 | 
			
		||||
| 
						 | 
				
			
			@ -38,6 +40,10 @@ in {
 | 
			
		|||
              ];
 | 
			
		||||
              passwordFile = config.age.secrets.theengs_ble_mqtt.path;
 | 
			
		||||
            };
 | 
			
		||||
            teslamate = {
 | 
			
		||||
              acl = ["readwrite teslamate/#"];
 | 
			
		||||
              passwordFile = config.age.secrets.teslamate_mqtt.path;
 | 
			
		||||
            };
 | 
			
		||||
          };
 | 
			
		||||
        }
 | 
			
		||||
      ];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										165
									
								
								modules/nixos/services/teslamate/default.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								modules/nixos/services/teslamate/default.nix
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,165 @@
 | 
			
		|||
{
 | 
			
		||||
  options,
 | 
			
		||||
  config,
 | 
			
		||||
  lib,
 | 
			
		||||
  pkgs,
 | 
			
		||||
  ...
 | 
			
		||||
}:
 | 
			
		||||
with lib; let
 | 
			
		||||
  cfg = config.aa.services.teslamate;
 | 
			
		||||
in {
 | 
			
		||||
  options.aa.services.teslamate = with types; {
 | 
			
		||||
    enable = mkEnableOption "teslamate";
 | 
			
		||||
 | 
			
		||||
    acmeCertName = mkOption {
 | 
			
		||||
      type = str;
 | 
			
		||||
      default = "";
 | 
			
		||||
      description = ''
 | 
			
		||||
        If set to a non-empty string, forces SSL with the supplied acme
 | 
			
		||||
        certificate.
 | 
			
		||||
      '';
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    user = mkOption {
 | 
			
		||||
      type = str;
 | 
			
		||||
      default = "teslamate";
 | 
			
		||||
      description = ''
 | 
			
		||||
        The user that should run teslamate
 | 
			
		||||
      '';
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    group = mkOption {
 | 
			
		||||
      type = str;
 | 
			
		||||
      default = "teslamate";
 | 
			
		||||
      description = ''
 | 
			
		||||
        The group that should be assigned to the user running teslamate
 | 
			
		||||
      '';
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    database = {
 | 
			
		||||
      host = mkOption {
 | 
			
		||||
        type = str;
 | 
			
		||||
        default = "127.0.0.1";
 | 
			
		||||
        description = ''
 | 
			
		||||
          Database host address
 | 
			
		||||
        '';
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      name = mkOption {
 | 
			
		||||
        type = str;
 | 
			
		||||
        default = "teslamate";
 | 
			
		||||
        description = ''
 | 
			
		||||
          The database name
 | 
			
		||||
        '';
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      user = mkOption {
 | 
			
		||||
        type = str;
 | 
			
		||||
        default = "teslamate";
 | 
			
		||||
        description = ''
 | 
			
		||||
          The user that should have access to the database
 | 
			
		||||
        '';
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      passwordFile = mkOption {
 | 
			
		||||
        type = path;
 | 
			
		||||
        description = lib.mdDoc ''
 | 
			
		||||
          A file containing the password corresponding to
 | 
			
		||||
          {option}`database.user`
 | 
			
		||||
        '';
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      createDatabase = mkOption {
 | 
			
		||||
        type = bool;
 | 
			
		||||
        default = false;
 | 
			
		||||
        description = ''
 | 
			
		||||
          Whether to create a local database automatically.
 | 
			
		||||
        '';
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  config = mkIf cfg.enable {
 | 
			
		||||
    age.secrets = {
 | 
			
		||||
      teslamate_encryption.file = ../../../../secrets/teslamate_encryption.age;
 | 
			
		||||
      teslamate_mqtt.file = ../../../../secrets/teslamate_mqtt.age;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    # docker-teslamate is the name of the service generated by the
 | 
			
		||||
    # `virtualisation.oci-contianers` block below
 | 
			
		||||
    systemd.services."docker-teslamate" = {
 | 
			
		||||
      preStart = ''
 | 
			
		||||
        mkdir -p /var/lib/teslamate
 | 
			
		||||
 | 
			
		||||
        # Create file if it doesn't exist, truncate it if does
 | 
			
		||||
        touch /var/lib/teslamate/env
 | 
			
		||||
        echo "" > /var/lib/teslamate/env
 | 
			
		||||
 | 
			
		||||
        chmod 600 /var/lib/teslamate/env
 | 
			
		||||
 | 
			
		||||
        echo ENCRYPTION_KEY="$(cat ${config.age.secrets.teslamate_encryption.path})" >> /var/lib/teslamate/env
 | 
			
		||||
        echo DATABASE_PASS="$(cat ${cfg.database.passwordFile})" >> /var/lib/teslamate/env
 | 
			
		||||
        echo MQTT_PASSWORD="$(cat ${config.age.secrets.teslamate_mqtt.path})" >> /var/lib/teslamate/env
 | 
			
		||||
      '';
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    virtualisation.oci-containers = {
 | 
			
		||||
      backend = "docker";
 | 
			
		||||
      containers."teslamate" = {
 | 
			
		||||
        image = "ghcr.io/teslamate-org/teslamate:latest";
 | 
			
		||||
        environmentFiles = ["/var/lib/teslamate/env"];
 | 
			
		||||
        environment = {
 | 
			
		||||
          # TODO: Make this configurable
 | 
			
		||||
          PORT = "4000";
 | 
			
		||||
          DATABASE_USER = cfg.database.user;
 | 
			
		||||
          DATABASE_NAME = cfg.database.name;
 | 
			
		||||
          DATABASE_HOST = cfg.database.host;
 | 
			
		||||
          # TODO: Make this configurable.
 | 
			
		||||
          MQTT_HOST = "192.168.113.42";
 | 
			
		||||
          MQTT_USERNAME = "teslamate";
 | 
			
		||||
          TZ = "America/Los_Angeles";
 | 
			
		||||
        };
 | 
			
		||||
        extraOptions = ["--cap-drop=all" "--network=host"];
 | 
			
		||||
        # TODO: Make this configurable
 | 
			
		||||
        ports = ["4000:4000"];
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    users.users.${cfg.user} = {
 | 
			
		||||
      isSystemUser = true;
 | 
			
		||||
      group = cfg.group;
 | 
			
		||||
    };
 | 
			
		||||
    users.groups.${cfg.group} = {};
 | 
			
		||||
 | 
			
		||||
    services.postgresql = optionalAttrs cfg.database.createDatabase {
 | 
			
		||||
      enable = mkDefault true;
 | 
			
		||||
 | 
			
		||||
      ensureDatabases = [cfg.database.name];
 | 
			
		||||
      ensureUsers = [
 | 
			
		||||
        {
 | 
			
		||||
          name = cfg.database.user;
 | 
			
		||||
          ensureDBOwnership = true;
 | 
			
		||||
        }
 | 
			
		||||
      ];
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    services.nginx = {
 | 
			
		||||
      enable = true;
 | 
			
		||||
      virtualHosts."teslamate.kilonull.com" =
 | 
			
		||||
        {
 | 
			
		||||
          locations."/" = {
 | 
			
		||||
            recommendedProxySettings = true;
 | 
			
		||||
            proxyWebsockets = true;
 | 
			
		||||
            # TODO: Make port configurable.
 | 
			
		||||
            proxyPass = "http://127.0.0.1:4000";
 | 
			
		||||
          };
 | 
			
		||||
        }
 | 
			
		||||
        // lib.optionalAttrs (cfg.acmeCertName != "") {
 | 
			
		||||
          forceSSL = true;
 | 
			
		||||
          useACMEHost = cfg.acmeCertName;
 | 
			
		||||
        };
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    networking.firewall.allowedTCPPorts = [4000];
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -6,13 +6,13 @@
 | 
			
		|||
}:
 | 
			
		||||
stdenv.mkDerivation rec {
 | 
			
		||||
  pname = "teslamate-grafana-dashboards";
 | 
			
		||||
  version = "1.28.2";
 | 
			
		||||
  version = "1.28.3";
 | 
			
		||||
 | 
			
		||||
  src = fetchFromGitHub {
 | 
			
		||||
    owner = "teslamate-org";
 | 
			
		||||
    repo = "teslamate";
 | 
			
		||||
    rev = "v${version}";
 | 
			
		||||
    hash = "sha256-CH3u6ijzvVdjfTVu06UcyW4NhVQKeUKtC/j+UeDELNc=";
 | 
			
		||||
    hash = "sha256-Iky9zWb3m/ex/amZw2dP5ZOpFw3uyg0JG6e9PkV+t4A=";
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  dontBuild = true;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -12,4 +12,7 @@ in {
 | 
			
		|||
  "nextcloud_admin.age".publicKeys = [users.me machines.node];
 | 
			
		||||
  "theengs_ble_mqtt.age".publicKeys = [users.me machines.pi4];
 | 
			
		||||
  "hass_mqtt.age".publicKeys = [users.me machines.pi4 machines.node];
 | 
			
		||||
  "teslamate_db.age".publicKeys = [users.me machines.node];
 | 
			
		||||
  "teslamate_mqtt.age".publicKeys = [users.me machines.pi4 machines.node];
 | 
			
		||||
  "teslamate_encryption.age".publicKeys = [users.me machines.node];
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										8
									
								
								secrets/teslamate_db.age
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								secrets/teslamate_db.age
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
age-encryption.org/v1
 | 
			
		||||
-> piv-p256 UIEGzg A2wMmiESse22Vlfg8lbSUz3t2GwGvTE49WPKV81egU0Z
 | 
			
		||||
I/7v83H42x/2hhOMRAbyUNgCY/GugzSHr9y4EFWZ3rc
 | 
			
		||||
-> ssh-ed25519 Yk7ehg CVe6AyDEb9Ulg5Zn5GQAoQT8jXBkjAWx6CP847XU118
 | 
			
		||||
HIaJ4+oos94I7m1UEEErP2jhYNhAmG8/RRmNZrWSxcE
 | 
			
		||||
--- U3FNQyx/Ncl59978k3kMtYKNZayk13gAubt+l5RqFJw
 | 
			
		||||
W½ÊSÖ4ÿÐB mHYªÖ܇nú`"ß|´¢wèH¦À’
 | 
			
		||||
Wˆ4›
 | 
			
		||||
							
								
								
									
										7
									
								
								secrets/teslamate_encryption.age
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								secrets/teslamate_encryption.age
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
age-encryption.org/v1
 | 
			
		||||
-> piv-p256 UIEGzg AuDH1UtCo2ABWz85Uq+kS9CA/X7ZMk4PwCbtSSMHU1rL
 | 
			
		||||
pNyYJm4Boy64z0+T9xW/Emgm3cT3oLXXpqtkSGFuWsE
 | 
			
		||||
-> ssh-ed25519 Yk7ehg MlNtvtKwytkGrlcF2kBdYA/X4EaCVxuDCPRLkn9qWgo
 | 
			
		||||
cC0+E8s0VAKSBojprhU23IP3q77x/VRS7tbfOpPAa10
 | 
			
		||||
--- c0LU0eTiBBo1puXxtpfWQM4iBJODzYZ0dAzGSheQ6Og
 | 
			
		||||
ñïËì;¨ðvø;ä×UG•óËDÉ.au¬¸#¬¿†Iüê±ß'<27>ÿ‡ÎI<øI¯‹´ý›viôºÕS9VnÎYþí
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								secrets/teslamate_mqtt.age
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								secrets/teslamate_mqtt.age
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -8,7 +8,10 @@
 | 
			
		|||
    ./zfs.nix
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  age.secrets.cf_dns_kilonull.file = ../../../secrets/cf_dns_kilonull.age;
 | 
			
		||||
  age.secrets = {
 | 
			
		||||
    cf_dns_kilonull.file = ../../../secrets/cf_dns_kilonull.age;
 | 
			
		||||
    teslamate_db.file = ../../../secrets/teslamate_db.age;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  aa = {
 | 
			
		||||
    nix.enable = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -47,6 +50,14 @@
 | 
			
		|||
      remoteTargetDatasets = ["tank/backups"];
 | 
			
		||||
      remoteTargetPublicKeys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAhA+9O2OBMDH1Xnj6isu36df5TOdZG8aEA4JpN2K60e syncoid@gospel"];
 | 
			
		||||
    };
 | 
			
		||||
    services.teslamate = {
 | 
			
		||||
      enable = true;
 | 
			
		||||
      database = {
 | 
			
		||||
        createDatabase = true;
 | 
			
		||||
        passwordFile = config.age.secrets.teslamate_db.path;
 | 
			
		||||
      };
 | 
			
		||||
      acmeCertName = "kilonull.com";
 | 
			
		||||
    };
 | 
			
		||||
    services.gitea = {
 | 
			
		||||
      enable = true;
 | 
			
		||||
      acmeCertName = "kilonull.com";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue