Skip to content

Commit 835a1d4

Browse files
Merge branch 'main' into dependabot/hex/ecto_sql-3.13.2
2 parents 485d493 + ac81e56 commit 835a1d4

12 files changed

Lines changed: 284 additions & 38 deletions

File tree

.github/workflows/update-flake-lock.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ jobs:
4343

4444
- name: Update flake.lock
4545
id: update
46-
uses: DeterminateSystems/update-flake-lock@428c2b58a4b7414dabd372acb6a03dba1084d3ab #v25
46+
uses: DeterminateSystems/update-flake-lock@c5930b397a673a70ca70be06020e943aeac310a1 #v27
4747
with:
4848
pr-title: "build(deps): update flake.lock"
4949
pr-labels: |

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,22 @@
44

55
### New features
66

7+
- feat(nix): add idiomatic maintenance scripts (#4849 - @JakobLichterfeld)
8+
79
### Improvements and bug fixes
810

911
- feat(webview): show offline duration in extended view on mobile as well to improve UX (#4848 - @JakobLichterfeld)
1012
- feat: use Grafana 12.1.0 (#4855 - @swiffer)
13+
- feat(nix): use datasources.settings.datasources to allow merging Grafana sources from multiple modules (#4870 - @JakobLichterfeld)
14+
- fix(nix): correctly set default Grafana dashboard path (#4870 - @JakobLichterfeld)
15+
- feat(nix): allow disabling default Grafana dashboard with setDefaultDashboard option (#4870 - @JakobLichterfeld)
1116

1217
#### Build, CI, internal
1318

1419
- style(issue-template): typo fix in Unraid (#4842 - @JakobLichterfeld)
1520
- build(deps): update flake.lock (#4858)
21+
- build(deps): bump DeterminateSystems/update-flake-lock from 25 to 27 (#4864)
22+
- build(deps): bump react and react-dom from 19.1.0 to 19.1.1 in /website (#4865 - @JakobLichterfeld)
1623
- build(deps): bump ecto_sql from 3.12.1 to 3.13.2 (#4863)
1724

1825
#### Dashboards
@@ -23,6 +30,9 @@
2330

2431
#### Documentation
2532

33+
- docs: add reference to idiomatic nix backup and restore scripts (#4849 - @JakobLichterfeld)
34+
- docs: add reference to idiomatic nix maintenance scripts (#4849 - @JakobLichterfeld)
35+
2636
## [2.1.0] - 2025-07-21
2737

2838
As always, there are many improvements. We have introduced new database fields to store the total ascent and descent of a drive, which can be used in the drives and efficiency dashboards. This is a valuable addition for users who wish to analyze their driving patterns and performance in hilly areas, and it enhances the efficiency metrics.

nix/maintenance.nix

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
{ stdenv
2+
, lib
3+
, pkgs
4+
, writeShellScript
5+
, databaseUser
6+
, databaseName
7+
, getExe
8+
, teslamate
9+
, environmentFilePath
10+
, ...
11+
}:
12+
let
13+
closeDrive = writeShellScript "teslamate-close-drive" ''
14+
set -euo pipefail
15+
: ''${1?'Please provide a drive ID to close'}
16+
17+
if ! [[ "''${1}" =~ ^[0-9]+$ ]]; then
18+
echo "Error: Drive ID must be an integer." >&2
19+
exit 1
20+
fi
21+
22+
# load env file to have RELEASE_COOKIE set
23+
if [ -f ${environmentFilePath} ]; then
24+
source ${environmentFilePath}
25+
export RELEASE_COOKIE
26+
else
27+
echo "Environment file ${environmentFilePath} not found!" >&2
28+
exit 1
29+
fi
30+
: ''${RELEASE_COOKIE?'RELEASE_COOKIE must be set in the environment file'}
31+
32+
echo "Attempt to close the drive with ID ''${1}."
33+
${getExe teslamate} rpc "TeslaMate.Repo.get!(TeslaMate.Log.Drive, ''${1}) |> TeslaMate.Log.close_drive()"
34+
'';
35+
36+
closeCharge = writeShellScript "teslamate-close-charge" ''
37+
set -euo pipefail
38+
: ''${1?'Please provide a charge ID to close'}
39+
40+
if ! [[ "''${1}" =~ ^[0-9]+$ ]]; then
41+
echo "Error: Charge ID must be an integer." >&2
42+
exit 1
43+
fi
44+
45+
# load env file to have RELEASE_COOKIE set
46+
if [ -f ${environmentFilePath} ]; then
47+
source ${environmentFilePath}
48+
export RELEASE_COOKIE
49+
else
50+
echo "Environment file ${environmentFilePath} not found!" >&2
51+
exit 1
52+
fi
53+
: ''${RELEASE_COOKIE?'RELEASE_COOKIE must be set in the environment file'}
54+
55+
echo "Attempt to close the charge with ID ''${1}."
56+
${getExe teslamate} rpc "TeslaMate.Repo.get!(TeslaMate.Log.ChargingProcess, ''${1}) |> TeslaMate.Log.complete_charging_process()"
57+
'';
58+
59+
deleteDrive = writeShellScript "teslamate-delete-drive" ''
60+
set -euo pipefail
61+
: ''${1?'Please provide a drive ID to delete'}
62+
63+
if ! [[ "''${1}" =~ ^[0-9]+$ ]]; then
64+
echo "Error: Drive ID must be an integer." >&2
65+
exit 1
66+
fi
67+
68+
# Check if drive exists
69+
if [ "$(sudo -u teslamate psql -U ${databaseUser} -d ${databaseName} -tAc "SELECT 1 FROM drives WHERE id = ''${1};")" != "1" ]; then
70+
echo "Warning: Drive with ID ''${1} does not exist. Nothing to delete." >&2
71+
exit 0
72+
fi
73+
74+
echo "Attempt to delete the drive with ID ''${1}."
75+
sudo -u teslamate psql -U ${databaseUser} -d ${databaseName} -c "DELETE FROM drives WHERE id = ''${1};"
76+
echo "Successfully deleted drive with ID ''${1}."
77+
'';
78+
79+
deleteCharge = writeShellScript "teslamate-delete-charge" ''
80+
set -euo pipefail
81+
: ''${1?'Please provide a charge ID to delete'}
82+
83+
if ! [[ "''${1}" =~ ^[0-9]+$ ]]; then
84+
echo "Error: Charge ID must be an integer." >&2
85+
exit 1
86+
fi
87+
88+
# Check if charging process exists
89+
if [ "$(sudo -u teslamate psql -U ${databaseUser} -d ${databaseName} -tAc "SELECT 1 FROM charging_processes WHERE id = ''${1};")" != "1" ]; then
90+
echo "Warning: Charging process with ID ''${1} does not exist. Nothing to delete." >&2
91+
exit 0
92+
fi
93+
94+
echo "Attempt to delete the charge with ID ''${1}."
95+
sudo -u teslamate psql -U ${databaseUser} -d ${databaseName} -c "DELETE FROM charging_processes WHERE id = ''${1};"
96+
echo "Successfully deleted charging process with ID ''${1}."
97+
'';
98+
in
99+
stdenv.mkDerivation {
100+
pname = "teslamate-maintenance";
101+
version = "0.1.0";
102+
src = ./.;
103+
104+
phases = [ "installPhase" ];
105+
106+
installPhase = ''
107+
mkdir -p $out/bin
108+
ln -s ${closeDrive} $out/bin/teslamate-close-drive
109+
ln -s ${closeCharge} $out/bin/teslamate-close-charge
110+
ln -s ${deleteDrive} $out/bin/teslamate-delete-drive
111+
ln -s ${deleteCharge} $out/bin/teslamate-delete-charge
112+
'';
113+
}

nix/module.nix

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,12 @@ in
137137
default = "/";
138138
description = "Path that grafana is mounted on. Useful if using a reverse proxy to vend teslamate and grafana on the same port";
139139
};
140+
141+
setDefaultDashboard = mkOption {
142+
type = types.bool;
143+
default = true;
144+
description = "Whether to set the TeslaMate home dashboard as the default dashboard in Grafana";
145+
};
140146
};
141147

142148
mqtt = {
@@ -207,12 +213,19 @@ in
207213
];
208214
};
209215

210-
# idiomatic backup and restore scripts
216+
# idiomatic backup and restore and maintenance scripts
211217
environment.systemPackages = with pkgs; [
212218
(callPackage ./backup_and_restore.nix {
213219
databaseUser = cfg.postgres.user;
214220
databaseName = cfg.postgres.database;
215221
})
222+
(callPackage ./maintenance.nix {
223+
databaseUser = cfg.postgres.user;
224+
databaseName = cfg.postgres.database;
225+
environmentFilePath = cfg.secretsFile;
226+
getExe = getExe;
227+
teslamate = teslamate;
228+
})
216229
];
217230
}
218231
(mkIf cfg.postgres.enable_server {
@@ -262,14 +275,34 @@ in
262275
"auth.anonymous".enabled = false;
263276
"auth.basic".enabled = false;
264277
analytics.reporting_enabled = false;
265-
dashboards.default_home_dashboard_path = "../grafana/dashboards/internal/home.json";
278+
dashboards.default_home_dashboard_path = mkIf cfg.grafana.setDefaultDashboard "${pkgs.lib.sources.sourceFilesBySuffices ../grafana/dashboards/internal [".json"]}/home.json";
266279
date_formats.use_browser_locale = true;
267280
plugins.preinstall_disabled = true;
268281
unified_alerting.enabled = false;
269282
};
270283
provision = {
271284
enable = true;
272-
datasources.path = ../grafana/datasource.yml;
285+
datasources.settings.datasources = [
286+
# extracted from ../grafana/datasource.yml
287+
{
288+
name = "TeslaMate";
289+
type = "postgres";
290+
url = "http://${cfg.postgres.host}:${toString cfg.postgres.port}";
291+
user = cfg.postgres.user;
292+
access = "proxy";
293+
basicAuth = false;
294+
withCredentials = false;
295+
isDefault = true;
296+
secureJsonData.password = "\${DATABASE_PASS}";
297+
jsonData = {
298+
postgresVersion = 1500;
299+
sslmode = "disable";
300+
database = cfg.postgres.database;
301+
};
302+
version = 1;
303+
editable = true;
304+
}
305+
];
273306
# Need to duplicate dashboards.yml since it contains absolute paths
274307
# which are incompatible with NixOS
275308
dashboards.settings = {

website/docs/import/tesla_apiscraper.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ This is a multi-step process to export your data from a [tesla-apiscraper](https
1111

1212
- A system running Docker with sufficient RAM for InfluxDB to perform the CSV export. This does **not** need to be the same machine where API Scraper and/or TeslaMate was/is running - you can do the export and conversion on your PC/Mac. The important thing is to give the Docker machine more than 2GB of RAM, otherwise the InfluxDB export may fail.
1313

14-
- **CREATE A [BACKUP](../maintenance/backup_restore.md) OF YOUR DATA** before attempting to import anything into TeslaMate. This is all highly experimental and has only been successfully done once :)
14+
- **CREATE A [BACKUP](../maintenance/backup_restore.mdx) OF YOUR DATA** before attempting to import anything into TeslaMate. This is all highly experimental and has only been successfully done once :)
1515

1616
## Instructions
1717

website/docs/import/teslafi.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ sidebar_label: TeslaFi
55

66
## Requirements
77

8-
- **CREATE A [BACKUP](../maintenance/backup_restore.md) OF YOUR DATA‼️**
8+
- **CREATE A [BACKUP](../maintenance/backup_restore.mdx) OF YOUR DATA‼️**
99

1010
- If you have been using TeslaMate since before the 1.16 release, the [docker-compose.yml](../installation/docker.md) needs to be updated. Add the following volume mapping to the `teslamate` service:
1111

website/docs/maintenance/backup_restore.md renamed to website/docs/maintenance/backup_restore.mdx

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,18 @@ If you are using `docker-compose`, you are using Docker Compose v1, which has be
1010

1111
Create backup file `teslamate.bck`:
1212

13+
import Tabs from "@theme/Tabs";
14+
import TabItem from "@theme/TabItem";
15+
16+
<Tabs
17+
defaultValue="dockerCompose"
18+
groupId="type"
19+
values={[
20+
{ label: 'Docker Compose', value: 'dockerCompose', },
21+
{ label: 'NixOS', value: 'nixos', },
22+
]}>
23+
<TabItem value="dockerCompose">
24+
1325
```bash
1426
docker compose exec -T database pg_dump -U teslamate teslamate > ./teslamate.bck
1527
```
@@ -30,8 +42,29 @@ If you get the error `No such service: database`, update your _docker-compose.ym
3042
If you changed `TM_DB_USER` in the .env file from one of the advanced guides, make sure to replace the first instance of `teslamate` to the value of `TM_DB_USER` in the above command.
3143
:::
3244

45+
</TabItem>
46+
<TabItem value="nixos">
47+
48+
You can use the idiomatic backup script:
49+
50+
```bash
51+
teslamate-backup teslamate_$(date +%Y%m%d-%H%M).bck
52+
```
53+
54+
</TabItem>
55+
</Tabs>
56+
3357
## Restore
3458

59+
<Tabs
60+
defaultValue="dockerCompose"
61+
groupId="type"
62+
values={[
63+
{ label: 'Docker Compose', value: 'dockerCompose', },
64+
{ label: 'NixOS', value: 'nixos', },
65+
]}>
66+
<TabItem value="dockerCompose">
67+
3568
:::note
3669
Replace the default `teslamate` value below with the value defined in the .env file if you have one (TM_DB_USER and TM_DB_NAME)
3770
:::
@@ -54,3 +87,15 @@ docker compose exec -T database psql -U teslamate -d teslamate < teslamate.bck
5487
# Restart the teslamate container
5588
docker compose start teslamate
5689
```
90+
91+
</TabItem>
92+
<TabItem value="nixos">
93+
94+
You can use the idiomatic restore script, for example:
95+
96+
```bash
97+
teslamate-restore teslamate_20250805-1622.bck
98+
```
99+
100+
</TabItem>
101+
</Tabs>

0 commit comments

Comments
 (0)