From 4cf670ae76185af82d5c241e3be03ea01e151ae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?PontualTech=20/=20Karl=C3=A3o?= Date: Wed, 29 Apr 2026 08:56:52 -0300 Subject: [PATCH] =?UTF-8?q?fix(ble):=20for=C3=A7a=20write=20em=20ff02=20me?= =?UTF-8?q?smo=20sem=20property=20declarada=20v1.10.14?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BMS chinês declara ff02 com property [read] apenas, MAS aceita writes em background. Plugin Capacitor força através (Android stack permite). Web Bluetooth do Chrome respeita spec — recusa writeValue se char não tem write/wnr declarado. Workaround: se nenhuma char tem write declarada, força usar primeira não-notify (geralmente ff02). Tenta writeValue mesmo assim. Browser pode lançar SecurityError, mas se BMS aceitar = funciona. Co-Authored-By: Claude Opus 4.7 (1M context) --- app/diario-bordo.html | 10 ++++++++-- server/public/index.html | 10 ++++++++-- server/public/sw.js | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) 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}`;