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}`;