diff --git a/app/diario-bordo.html b/app/diario-bordo.html index 3dacbfc..3b47fe8 100644 --- a/app/diario-bordo.html +++ b/app/diario-bordo.html @@ -6161,9 +6161,23 @@ async function bmsProbeWebBluetooth(deviceId,deviceName){ await new Promise(r=>setTimeout(r,2500)); const dev=state.btDevices?.find(d=>d.id===deviceId); if(dev?.bms?.voltage||dev?._lastRxAt){ - setBleDiag(`✓ ${p.name} respondeu!`,'ok'); + setBleDiag(`✓ ${p.name} respondeu! · polling 5s ativado`,'ok'); if(dev){dev.bmsProtocol=p.name;dev.isJBD=true;saveState()} conn.notifyChar=notifyChar;conn.writeChar=writeChar; + // Polling a cada 5s pra atualização contínua + if(conn._pollInterval)clearInterval(conn._pollInterval); + conn._pollInterval=setInterval(async()=>{ + try{ + const fn2=writeChar.properties.writeWithoutResponse?'writeValueWithoutResponse':'writeValue'; + await writeChar[fn2](new Uint8Array(p.bytes)); + }catch(e){ + // Conexão caiu: para o polling + if(/disconnected|connection|gatt/i.test(e.message||'')){ + setBleDiag('Polling interrompido: '+e.message,'warn'); + clearInterval(conn._pollInterval);conn._pollInterval=null; + } + } + },5000); return true; } setBleDiag(`✗ ${p.name} sem RX`,'info'); @@ -6303,9 +6317,21 @@ async function bmsTryProtocols(deviceId){ await new Promise(r=>setTimeout(r,2500)); const dev=state.btDevices?.find(d=>d.id===deviceId); if(dev?.bms?.voltage||dev?._lastRxAt){ - setBleDiag(`✓ ${p.name} respondeu!`,'ok'); + setBleDiag(`✓ ${p.name} respondeu! · polling 5s ativado`,'ok'); if(dev)dev.bmsProtocol=p.name; - setInterval(async()=>{try{await bmsWriteCmd(deviceId,p.bytes,p.wnr)}catch{}},30000); + // Polling 5s pra atualização contínua (era 30s — usuário queria constante) + const conn=_bleConnections.get(deviceId)||{}; + if(conn._pollInterval)clearInterval(conn._pollInterval); + conn._pollInterval=setInterval(async()=>{ + try{await bmsWriteCmd(deviceId,p.bytes,p.wnr)} + catch(e){ + if(/disconnected|connection|not connected/i.test(e.message||e.errorMessage||'')){ + clearInterval(conn._pollInterval);conn._pollInterval=null; + setBleDiag('Polling parou: GATT desconectou','warn'); + } + } + },5000); + _bleConnections.set(deviceId,conn); return true; }else{ setBleDiag(`✗ ${p.name} sem RX em 2.5s`,'info'); @@ -6480,7 +6506,7 @@ async function removeBluetoothDevice(id){ renderBluetoothCard(); } -const APP_VERSION='1.10.18'; +const APP_VERSION='1.10.19'; function renderBluetoothCard(){ const el=document.getElementById('bt-list'); const supportEl=document.getElementById('bt-support'); diff --git a/server/public/index.html b/server/public/index.html index 3dacbfc..3b47fe8 100644 --- a/server/public/index.html +++ b/server/public/index.html @@ -6161,9 +6161,23 @@ async function bmsProbeWebBluetooth(deviceId,deviceName){ await new Promise(r=>setTimeout(r,2500)); const dev=state.btDevices?.find(d=>d.id===deviceId); if(dev?.bms?.voltage||dev?._lastRxAt){ - setBleDiag(`✓ ${p.name} respondeu!`,'ok'); + setBleDiag(`✓ ${p.name} respondeu! · polling 5s ativado`,'ok'); if(dev){dev.bmsProtocol=p.name;dev.isJBD=true;saveState()} conn.notifyChar=notifyChar;conn.writeChar=writeChar; + // Polling a cada 5s pra atualização contínua + if(conn._pollInterval)clearInterval(conn._pollInterval); + conn._pollInterval=setInterval(async()=>{ + try{ + const fn2=writeChar.properties.writeWithoutResponse?'writeValueWithoutResponse':'writeValue'; + await writeChar[fn2](new Uint8Array(p.bytes)); + }catch(e){ + // Conexão caiu: para o polling + if(/disconnected|connection|gatt/i.test(e.message||'')){ + setBleDiag('Polling interrompido: '+e.message,'warn'); + clearInterval(conn._pollInterval);conn._pollInterval=null; + } + } + },5000); return true; } setBleDiag(`✗ ${p.name} sem RX`,'info'); @@ -6303,9 +6317,21 @@ async function bmsTryProtocols(deviceId){ await new Promise(r=>setTimeout(r,2500)); const dev=state.btDevices?.find(d=>d.id===deviceId); if(dev?.bms?.voltage||dev?._lastRxAt){ - setBleDiag(`✓ ${p.name} respondeu!`,'ok'); + setBleDiag(`✓ ${p.name} respondeu! · polling 5s ativado`,'ok'); if(dev)dev.bmsProtocol=p.name; - setInterval(async()=>{try{await bmsWriteCmd(deviceId,p.bytes,p.wnr)}catch{}},30000); + // Polling 5s pra atualização contínua (era 30s — usuário queria constante) + const conn=_bleConnections.get(deviceId)||{}; + if(conn._pollInterval)clearInterval(conn._pollInterval); + conn._pollInterval=setInterval(async()=>{ + try{await bmsWriteCmd(deviceId,p.bytes,p.wnr)} + catch(e){ + if(/disconnected|connection|not connected/i.test(e.message||e.errorMessage||'')){ + clearInterval(conn._pollInterval);conn._pollInterval=null; + setBleDiag('Polling parou: GATT desconectou','warn'); + } + } + },5000); + _bleConnections.set(deviceId,conn); return true; }else{ setBleDiag(`✗ ${p.name} sem RX em 2.5s`,'info'); @@ -6480,7 +6506,7 @@ async function removeBluetoothDevice(id){ renderBluetoothCard(); } -const APP_VERSION='1.10.18'; +const APP_VERSION='1.10.19'; function renderBluetoothCard(){ const el=document.getElementById('bt-list'); const supportEl=document.getElementById('bt-support'); diff --git a/server/public/sw.js b/server/public/sw.js index 8d8919d..1949b26 100644 --- a/server/public/sw.js +++ b/server/public/sw.js @@ -1,7 +1,7 @@ // Shivao Service Worker — offline real // Estratégia: shell precachado, tiles cache-first, windy network-first, /api passa direto. // Versão usada nos cache names — bumpa essa string pra invalidar caches antigos em deploys. -const VERSION = 'shivao-v1.10.18'; +const VERSION = 'shivao-v1.10.19'; const SHELL_CACHE = `shivao-shell-${VERSION}`; const TILES_CACHE = 'shivao-tiles-v1'; // separado pra não invalidar tiles em update do shell const WINDY_CACHE = `shivao-windy-${VERSION}`;