diff --git a/web/app.js b/web/app.js index 5be4743..a2ebb7b 100644 --- a/web/app.js +++ b/web/app.js @@ -99,11 +99,8 @@ async function discoverServices() { // Initial read so values show immediately parseTelemetry(await chars.telemetry.readValue()); - // IMU stream notify (~100 Hz) + // IMU stream — subscribed on demand via play button chars.imuStream.addEventListener('characteristicvaluechanged', e => parseImuStream(e.target.value)); - await chars.imuStream.startNotifications(); - document.getElementById('vizLive').classList.add('on'); - log('IMU stream subscribed','ok'); log('Config service ready (4 chars)','ok'); } catch(e) { @@ -396,7 +393,7 @@ function onDisconnected() { document.getElementById('battBar').style.display='none'; document.getElementById('badgeCharging').classList.remove('show'); document.getElementById('badgeFull').classList.remove('show'); - document.getElementById('vizLive').classList.remove('on'); + imuSubscribed = false; vizPaused = true; vizUpdateIndicator(); clearTelemetry(); if (!userDisconnected && document.getElementById('autoReconnect').checked && savedDevice) { log('Auto-reconnecting…','info'); @@ -426,8 +423,43 @@ const canvas = document.getElementById('vizCanvas'); const ctx = canvas.getContext('2d'); const TRAIL_LEN = 120; let cursorX = canvas.width/2, cursorY = canvas.height/2, trail = []; +let vizPaused = true; +let imuSubscribed = false; + +function vizUpdateIndicator() { + const el = document.getElementById('vizLive'); + if (!imuSubscribed || vizPaused) { + el.classList.remove('on'); + el.classList.add('paused'); + el.textContent = '⏸ PAUSED'; + } else { + el.classList.add('on'); + el.classList.remove('paused'); + el.textContent = '● LIVE'; + } + document.getElementById('vizPauseBtn').style.display = (!vizPaused && imuSubscribed) ? '' : 'none'; + document.getElementById('vizPlayBtn').style.display = (vizPaused || !imuSubscribed) ? '' : 'none'; +} + +async function vizSetPaused(paused) { + vizPaused = paused; + if (!paused && chars.imuStream && !imuSubscribed) { + try { + await chars.imuStream.startNotifications(); + imuSubscribed = true; + log('IMU stream subscribed','ok'); + } catch(e) { log(`IMU stream start failed: ${e.message}`,'err'); vizPaused = true; } + } else if (paused && imuSubscribed) { + try { + await chars.imuStream.stopNotifications(); + imuSubscribed = false; + } catch(e) { log(`IMU stream stop failed: ${e.message}`,'err'); } + } + vizUpdateIndicator(); +} function parseImuStream(dv) { + if (vizPaused) return; let view; try { view = dv instanceof DataView ? new DataView(dv.buffer, dv.byteOffset, dv.byteLength) : new DataView(dv); diff --git a/web/index.html b/web/index.html index 336e9e6..b6d7d7e 100644 --- a/web/index.html +++ b/web/index.html @@ -158,7 +158,11 @@