diff --git a/HEARTBEAT.md b/HEARTBEAT.md index 757ae76..604d628 100644 --- a/HEARTBEAT.md +++ b/HEARTBEAT.md @@ -30,6 +30,41 @@ curl -s --connect-timeout 2 http://localhost:5557/health > /dev/null 2>&1 || bas If Flask responded (exit 0) — do nothing, reply HEARTBEAT_OK. If not running — start it and report: "🚀 snowbike-rag restarted on port 5557". +## 🏔️ Watchdog: Terrain hillshade generation + +Проверять статус генерации hillshade тайлов каждые 30 минут и отписываться Славе. + +```shell +cd /home/node/.openclaw/workspace/tasks/enduro-trails/prototype && node -e " +const { Client } = require('ssh2'); +const conn = new Client(); +function exec(conn, cmd) { + return new Promise((resolve, reject) => { + conn.exec(cmd, (err, stream) => { + if (err) return reject(err); + let out = '', e = ''; + stream.on('data', d => out += d); + stream.stderr.on('data', d => e += d); + stream.on('close', () => resolve({ out: out.trim(), err: e.trim() })); + }); + }); +} +conn.on('ready', async () => { + const zooms = await exec(conn, 'ls /home/slin/enduro-trails/data/terrain/hillshade/ 2>/dev/null | grep -v xml | sort -n | tr \\\"\\n\\\" \\\" \\\"'); + const pngs = await exec(conn, 'find /home/slin/enduro-trails/data/terrain/hillshade -name \\\"*.png\\\" 2>/dev/null | wc -l'); + const procs = await exec(conn, 'pgrep -c gdal2tiles 2>/dev/null || echo 0'); + console.log('zooms:' + zooms.out + ' pngs:' + pngs.out + ' procs:' + procs.out); + conn.end(); +}); +conn.connect({ host: '82.22.50.71', username: 'slin', password: 'motoZ@yaz2010', readyTimeout: 15000 }); +" 2>/dev/null +``` + +Если `procs: 0` И зумы 10-15 все есть → hillshade готов → запустить ручные тесты TC-07..TC-25 и отписаться Славе. +Если ещё идёт → отписаться: «🏔️ Hillshade: зумы X, PNGs Y, ещё генерируется». + +--- + ## 🌐 Watchdog: vpn-srv FRP tunnel Check if vpn-srv FRP tunnel is active (port 3322 on relay).