Files
EVCS/tools/ha-backup-list.mjs
Tallagrand Thierry 57c696928d Sauvegarde Home Assistant : configuree, poussee sur deux autres machines, verifiee
Aucune sauvegarde HA n avait jamais ete faite, et git ne la couvrait pas
-- un seul fichier HA y etait versionne. HA declarait pourtant trois
destinations Synology, dont 10.10.10.22 et une troisieme machine en
10.10.10.50 absente de toute la documentation du projet.

Quotidienne 04:45, sept copies, base d historique exclue (20 Mo au lieu
de 4,4 Go), poussee sur les trois machines. La configuration passe par
le websocket car l API REST ne l expose pas.

Verifiee archive en main : .storage, packages, dashboards, secrets et
custom_components presents, base d historique absente comme voulu.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
2026-09-01 03:13:55 +02:00

49 lines
2.2 KiB
JavaScript

#!/usr/bin/env node
// Liste les sauvegardes Home Assistant et, pour chacune, les destinations où
// elle est RÉELLEMENT présente. C'est cette dernière colonne qui compte : une
// sauvegarde qui n'existe que sur la machine dont on se protège ne protège rien.
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
const HA_URL = process.env.HA_URL || 'http://10.10.10.17:8123';
const token = process.env.HA_TOKEN ||
fs.readFileSync(path.join(ROOT, '.env'), 'utf8').match(/^\s*HA_TOKEN\s*=\s*(.+?)\s*$/m)[1].replace(/^["']|["']$/g, '');
const HOST = {
'backup.local': '10.10.10.17 (local)',
'synology_dsm.1660NZN396007': '10.10.10.22',
'synology_dsm.14B0MPN914514': '10.10.10.50',
'synology_dsm.20A0SBRVM9PF2': '10.10.10.17',
};
const ws = new WebSocket(HA_URL.replace(/^http/, 'ws') + '/api/websocket');
ws.onmessage = (ev) => {
const m = JSON.parse(ev.data);
if (m.type === 'auth_required') return ws.send(JSON.stringify({ type: 'auth', access_token: token }));
if (m.type === 'auth_ok') return ws.send(JSON.stringify({ id: 1, type: 'backup/info' }));
if (m.type === 'result') {
const r = m.result || {};
if (r.backups?.length) {
for (const b of r.backups) {
const mo = (b.agents ? Object.entries(b.agents) : []);
console.log(`\n${b.name} (${b.backup_id})`);
console.log(` créée : ${new Date(b.date).toLocaleString('fr-FR', { timeZone: 'Europe/Paris' })}`);
console.log(` base incluse : ${b.database_included} automatique : ${b.with_automatic_settings}`);
for (const [agent, info] of mo) {
const mb = info.size ? (info.size / 1048576).toFixed(1) + ' Mo' : '?';
console.log(` → ${(HOST[agent] || agent).padEnd(22)} ${mb.padStart(9)}`);
}
}
} else {
console.log('Aucune sauvegarde.');
}
if (r.next_automatic_backup) {
console.log(`\nProchaine automatique : ${new Date(r.next_automatic_backup).toLocaleString('fr-FR', { timeZone: 'Europe/Paris' })}`);
}
ws.close(); process.exit(0);
}
};
setTimeout(() => { console.error('délai dépassé'); process.exit(1); }, 30000);