Fix Bosch BLE protocol: correct UUIDs, 2-byte data IDs, new dashboard fields

This commit is contained in:
Admin 2026-03-21 15:37:13 +00:00
parent 906fde8ad1
commit b5dd24544c

View File

@ -1,11 +1,16 @@
/** /**
* BLE Service Web Bluetooth connection to Bosch Smart System * BLE Service Web Bluetooth connection to Bosch Smart System
*
* Connects via the correct Bosch eaa2 service UUID,
* subscribes to notifications on char 0011,
* and passes decoded data to the app.
*/ */
const BLEService = (() => { const BLEService = (() => {
let device = null; let device = null;
let server = null; let server = null;
let characteristic = null; let characteristic = null;
let writeCharacteristic = null;
let onDataCallback = null; let onDataCallback = null;
let onStatusCallback = null; let onStatusCallback = null;
@ -27,9 +32,10 @@ const BLEService = (() => {
updateStatus('scanning'); updateStatus('scanning');
try { try {
// Request device — use namePrefix filters + optionalServices
// (some Bosch bikes don't advertise the service UUID directly)
device = await navigator.bluetooth.requestDevice({ device = await navigator.bluetooth.requestDevice({
filters: [ filters: [
{ services: [BoschProtocol.SERVICE_UUID] },
{ namePrefix: 'smart system' }, { namePrefix: 'smart system' },
{ namePrefix: 'Bosch' }, { namePrefix: 'Bosch' },
{ namePrefix: 'BRC' } { namePrefix: 'BRC' }
@ -44,9 +50,19 @@ const BLEService = (() => {
updateStatus('discovering'); updateStatus('discovering');
const service = await server.getPrimaryService(BoschProtocol.SERVICE_UUID); const service = await server.getPrimaryService(BoschProtocol.SERVICE_UUID);
// Get notify characteristic (0011)
characteristic = await service.getCharacteristic(BoschProtocol.CHAR_UUID); characteristic = await service.getCharacteristic(BoschProtocol.CHAR_UUID);
// Subscribe to notifications // Try to get write characteristic (0012) for potential init commands
try {
writeCharacteristic = await service.getCharacteristic(BoschProtocol.WRITE_UUID);
console.log('Write characteristic (0012) available');
} catch (e) {
console.log('Write characteristic not available:', e.message);
}
// Subscribe to notifications IMMEDIATELY
await characteristic.startNotifications(); await characteristic.startNotifications();
characteristic.addEventListener('characteristicvaluechanged', onCharacteristicChanged); characteristic.addEventListener('characteristicvaluechanged', onCharacteristicChanged);
@ -71,6 +87,7 @@ const BLEService = (() => {
characteristic.removeEventListener('characteristicvaluechanged', onCharacteristicChanged); characteristic.removeEventListener('characteristicvaluechanged', onCharacteristicChanged);
characteristic = null; characteristic = null;
} }
writeCharacteristic = null;
if (device && device.gatt.connected) { if (device && device.gatt.connected) {
device.gatt.disconnect(); device.gatt.disconnect();
} }
@ -84,6 +101,14 @@ const BLEService = (() => {
*/ */
function onCharacteristicChanged(event) { function onCharacteristicChanged(event) {
const dataView = event.target.value; const dataView = event.target.value;
// Log raw bytes for debugging
const raw = [];
for (let i = 0; i < dataView.byteLength; i++) {
raw.push(dataView.getUint8(i).toString(16).toUpperCase().padStart(2, '0'));
}
console.log('BLE notification:', raw.join('-'), `(${dataView.byteLength}B)`);
const parsed = BoschProtocol.parseNotification(dataView); const parsed = BoschProtocol.parseNotification(dataView);
if (onDataCallback) { if (onDataCallback) {
onDataCallback(parsed); onDataCallback(parsed);
@ -96,6 +121,7 @@ const BLEService = (() => {
function onDisconnected() { function onDisconnected() {
console.warn('BLE device disconnected'); console.warn('BLE device disconnected');
characteristic = null; characteristic = null;
writeCharacteristic = null;
server = null; server = null;
updateStatus('disconnected'); updateStatus('disconnected');
} }