diff --git a/app/diario-bordo.html b/app/diario-bordo.html index abe1dd6..384b412 100644 --- a/app/diario-bordo.html +++ b/app/diario-bordo.html @@ -6079,7 +6079,13 @@ async function bmsProbeWebBluetooth(deviceId,deviceName){ if(!notifyChar&&(p.notify||p.indicate))notifyChar=c; if(!writeChar&&(p.write||p.writeWithoutResponse))writeChar=c; } - if(!notifyChar||!writeChar){setBleDiag('Sem chars notify+write','err');return false} + if(!notifyChar){setBleDiag('Sem char notify','err');return false} + if(!writeChar){ + // Workaround: BMS chinês declara ff02 só [read] mas aceita writes (firmware permissivo). + // Força usar primeira char não-notify e tenta writeValue mesmo assim. + writeChar=chars.find(c=>c.uuid.toLowerCase()!==notifyChar.uuid.toLowerCase())||chars[0]; + setBleDiag(`⚠ Sem property write · forçando ${writeChar.uuid.slice(4,8)}`,'warn'); + } setBleDiag(`Notify=${notifyChar.uuid.slice(4,8)} Write=${writeChar.uuid.slice(4,8)}`,'ok'); notifyChar.addEventListener('characteristicvaluechanged',(ev)=>{ const dv=ev.target.value; @@ -6440,7 +6446,7 @@ async function removeBluetoothDevice(id){ renderBluetoothCard(); } -const APP_VERSION='1.10.13'; +const APP_VERSION='1.10.14'; 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 abe1dd6..384b412 100644 --- a/server/public/index.html +++ b/server/public/index.html @@ -6079,7 +6079,13 @@ async function bmsProbeWebBluetooth(deviceId,deviceName){ if(!notifyChar&&(p.notify||p.indicate))notifyChar=c; if(!writeChar&&(p.write||p.writeWithoutResponse))writeChar=c; } - if(!notifyChar||!writeChar){setBleDiag('Sem chars notify+write','err');return false} + if(!notifyChar){setBleDiag('Sem char notify','err');return false} + if(!writeChar){ + // Workaround: BMS chinês declara ff02 só [read] mas aceita writes (firmware permissivo). + // Força usar primeira char não-notify e tenta writeValue mesmo assim. + writeChar=chars.find(c=>c.uuid.toLowerCase()!==notifyChar.uuid.toLowerCase())||chars[0]; + setBleDiag(`⚠ Sem property write · forçando ${writeChar.uuid.slice(4,8)}`,'warn'); + } setBleDiag(`Notify=${notifyChar.uuid.slice(4,8)} Write=${writeChar.uuid.slice(4,8)}`,'ok'); notifyChar.addEventListener('characteristicvaluechanged',(ev)=>{ const dv=ev.target.value; @@ -6440,7 +6446,7 @@ async function removeBluetoothDevice(id){ renderBluetoothCard(); } -const APP_VERSION='1.10.13'; +const APP_VERSION='1.10.14'; 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 da916c4..cbab32c 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.13'; +const VERSION = 'shivao-v1.10.14'; 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}`;