feat(bms): polling 5s constante no Web + Capacitor v1.10.19
Some checks are pending
Build Android (APK + AAB) / build-android (push) Waiting to run

Karlão: 'no PC monitoramento deveria ser constante mas conecta, mostra
informação e não atualiza'.

Bug encontrado: bmsProbeWebBluetooth não tinha setInterval — apenas
fazia uma leitura inicial. Apenas o path Capacitor tinha polling de
30s (que mesmo assim era lento).

Fix:
- Web: novo setInterval(5000) chamando writeValue/writeValueWithoutResponse
- Capacitor: 30s → 5s
- Ambos param polling automaticamente se conexão GATT cair (regex
  detecta 'disconnected/connection/not connected' no error)
- Salva referência em conn._pollInterval pra clearInterval limpo

Resultado: card BMS atualiza V/A/SoC/células a cada 5s sem usuário
fazer nada. Dashboard fica 'live'.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
PontualTech / Karlão 2026-04-29 19:17:16 -03:00
parent 0c0b2d2825
commit 654e597bf5
3 changed files with 61 additions and 9 deletions

View file

@ -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');

View file

@ -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');

View file

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