fix(ble): writeWithoutResponse forçado quando ff02 só tem wnr v1.10.7
Some checks are pending
Build Android (APK + AAB) / build-android (push) Waiting to run
Some checks are pending
Build Android (APK + AAB) / build-android (push) Waiting to run
DESCOBERTA crítica do log do Karlão: ff02 (write char) tem properties [wnr,read] — SÓ writeWithoutResponse, sem write. Meu probe primeiro tentava ble.write() (com response) que trava silenciosamente esperando ACK que o BMS nunca envia. Por isso log para em '→ TX JBD-0x03' sem testar próximos protocolos. Fix: - Probe detecta properties da writeChar e seta dev.bmsForceWnr=true quando char tem wnr mas não write - Log mostra '(force-wnr)' ao lado do Write= no diagnóstico - bmsWriteCmd respeita bmsForceWnr e usa writeWithoutResponse mesmo quando o protocol não pediu Esperado v1.10.7: TX JBD-0x03 com writeWithoutResponse → BMS responde com pacote 0xDD ... 0x77 → dashboard mostra V/A/SoC/células reais. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
cd4aa9c753
commit
6680f8b09b
5 changed files with 38 additions and 10 deletions
|
|
@ -6057,7 +6057,18 @@ async function bmsProbeAndAttach(deviceId,deviceName){
|
|||
setBleDiag('Não achei chars notify+write em services vendor','err');
|
||||
return false;
|
||||
}
|
||||
setBleDiag(`Notify=${notifyChar.slice(4,8)} Write=${writeChar.slice(4,8)} Svc=${foundService.slice(4,8)}`,'ok');
|
||||
// Detecta se write char só aceita writeWithoutResponse
|
||||
let writeOnlyWnr=false;
|
||||
for(const svc of allSvcs){
|
||||
if((svc.uuid||'').toLowerCase()!==foundService)continue;
|
||||
for(const c of (svc.characteristics||[])){
|
||||
if((c.uuid||'').toLowerCase()===writeChar){
|
||||
const p=c.properties||{};
|
||||
writeOnlyWnr=(!p.write&&p.writeWithoutResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
setBleDiag(`Notify=${notifyChar.slice(4,8)} Write=${writeChar.slice(4,8)}${writeOnlyWnr?' (force-wnr)':''} Svc=${foundService.slice(4,8)}`,'ok');
|
||||
// Subscribe + handler
|
||||
const listenerKey='notification|'+deviceId+'|'+foundService+'|'+notifyChar;
|
||||
ble.addListener(listenerKey,(ev)=>{
|
||||
|
|
@ -6079,6 +6090,7 @@ async function bmsProbeAndAttach(deviceId,deviceName){
|
|||
dev.bmsService=foundService;
|
||||
dev.bmsNotifyChar=notifyChar;
|
||||
dev.bmsWriteChar=writeChar;
|
||||
dev.bmsForceWnr=writeOnlyWnr;
|
||||
dev.isJBD=true;
|
||||
saveState();
|
||||
}
|
||||
|
|
@ -6094,7 +6106,9 @@ async function bmsWriteCmd(deviceId,bytes,withoutResponse){
|
|||
const ble=window.Capacitor?.Plugins?.BluetoothLe;
|
||||
const dev=state.btDevices?.find(d=>d.id===deviceId);
|
||||
if(!ble||!dev?.bmsService||!dev?.bmsWriteChar)throw new Error('config BMS ausente');
|
||||
const fn=withoutResponse?'writeWithoutResponse':'write';
|
||||
// Se a write char só aceita wnr, força writeWithoutResponse independente do parâmetro
|
||||
const useWnr=withoutResponse||dev.bmsForceWnr;
|
||||
const fn=useWnr?'writeWithoutResponse':'write';
|
||||
await ble[fn]({deviceId,service:dev.bmsService,characteristic:dev.bmsWriteChar,value:bytesToBase64(bytes)});
|
||||
}
|
||||
|
||||
|
|
@ -6289,7 +6303,7 @@ async function removeBluetoothDevice(id){
|
|||
renderBluetoothCard();
|
||||
}
|
||||
|
||||
const APP_VERSION='1.10.6';
|
||||
const APP_VERSION='1.10.7';
|
||||
function renderBluetoothCard(){
|
||||
const el=document.getElementById('bt-list');
|
||||
const supportEl=document.getElementById('bt-support');
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ android {
|
|||
applicationId "br.com.pontualtech.shivao"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 22
|
||||
versionName "1.10.6"
|
||||
versionCode 23
|
||||
versionName "1.10.7"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
aaptOptions {
|
||||
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "shivao-mobile",
|
||||
"version": "1.10.6",
|
||||
"version": "1.10.7",
|
||||
"description": "Shivao app nativo (Capacitor wrapper Android/iOS)",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
|
|
|
|||
|
|
@ -6057,7 +6057,18 @@ async function bmsProbeAndAttach(deviceId,deviceName){
|
|||
setBleDiag('Não achei chars notify+write em services vendor','err');
|
||||
return false;
|
||||
}
|
||||
setBleDiag(`Notify=${notifyChar.slice(4,8)} Write=${writeChar.slice(4,8)} Svc=${foundService.slice(4,8)}`,'ok');
|
||||
// Detecta se write char só aceita writeWithoutResponse
|
||||
let writeOnlyWnr=false;
|
||||
for(const svc of allSvcs){
|
||||
if((svc.uuid||'').toLowerCase()!==foundService)continue;
|
||||
for(const c of (svc.characteristics||[])){
|
||||
if((c.uuid||'').toLowerCase()===writeChar){
|
||||
const p=c.properties||{};
|
||||
writeOnlyWnr=(!p.write&&p.writeWithoutResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
setBleDiag(`Notify=${notifyChar.slice(4,8)} Write=${writeChar.slice(4,8)}${writeOnlyWnr?' (force-wnr)':''} Svc=${foundService.slice(4,8)}`,'ok');
|
||||
// Subscribe + handler
|
||||
const listenerKey='notification|'+deviceId+'|'+foundService+'|'+notifyChar;
|
||||
ble.addListener(listenerKey,(ev)=>{
|
||||
|
|
@ -6079,6 +6090,7 @@ async function bmsProbeAndAttach(deviceId,deviceName){
|
|||
dev.bmsService=foundService;
|
||||
dev.bmsNotifyChar=notifyChar;
|
||||
dev.bmsWriteChar=writeChar;
|
||||
dev.bmsForceWnr=writeOnlyWnr;
|
||||
dev.isJBD=true;
|
||||
saveState();
|
||||
}
|
||||
|
|
@ -6094,7 +6106,9 @@ async function bmsWriteCmd(deviceId,bytes,withoutResponse){
|
|||
const ble=window.Capacitor?.Plugins?.BluetoothLe;
|
||||
const dev=state.btDevices?.find(d=>d.id===deviceId);
|
||||
if(!ble||!dev?.bmsService||!dev?.bmsWriteChar)throw new Error('config BMS ausente');
|
||||
const fn=withoutResponse?'writeWithoutResponse':'write';
|
||||
// Se a write char só aceita wnr, força writeWithoutResponse independente do parâmetro
|
||||
const useWnr=withoutResponse||dev.bmsForceWnr;
|
||||
const fn=useWnr?'writeWithoutResponse':'write';
|
||||
await ble[fn]({deviceId,service:dev.bmsService,characteristic:dev.bmsWriteChar,value:bytesToBase64(bytes)});
|
||||
}
|
||||
|
||||
|
|
@ -6289,7 +6303,7 @@ async function removeBluetoothDevice(id){
|
|||
renderBluetoothCard();
|
||||
}
|
||||
|
||||
const APP_VERSION='1.10.6';
|
||||
const APP_VERSION='1.10.7';
|
||||
function renderBluetoothCard(){
|
||||
const el=document.getElementById('bt-list');
|
||||
const supportEl=document.getElementById('bt-support');
|
||||
|
|
|
|||
|
|
@ -347,7 +347,7 @@ app.get('/.well-known/assetlinks.json', (req, res) => {
|
|||
});
|
||||
|
||||
// Atalho: /apk redireciona pra última APK release no Forgejo
|
||||
const LATEST_APK_URL = 'https://git.pontualtech.work/karlao/shivao-projeto/releases/download/v1.10.6/Shivao-v1.10.6.apk';
|
||||
const LATEST_APK_URL = 'https://git.pontualtech.work/karlao/shivao-projeto/releases/download/v1.10.7/Shivao-v1.10.7.apk';
|
||||
app.get('/apk', (req, res) => res.redirect(302, LATEST_APK_URL));
|
||||
|
||||
// Página A4 imprimível com QR Code + instruções (cola no barco/marina)
|
||||
|
|
|
|||
Loading…
Reference in a new issue