mirror of https://github.com/espruino/BangleApps
bthrm 0.11: App now shows status info while connecting
+ Fixes to allow cached BluetoothRemoteGATTCharacteristic to work with 2v14.14 onwards (>1 central)pull/2016/head
parent
ae3f61b13c
commit
20d5bae555
|
@ -23,3 +23,5 @@
|
||||||
0.08: Allow scanning for devices in settings
|
0.08: Allow scanning for devices in settings
|
||||||
0.09: Misc Fixes and improvements (https://github.com/espruino/BangleApps/pull/1655)
|
0.09: Misc Fixes and improvements (https://github.com/espruino/BangleApps/pull/1655)
|
||||||
0.10: Use default Bangle formatter for booleans
|
0.10: Use default Bangle formatter for booleans
|
||||||
|
0.11: App now shows status info while connecting
|
||||||
|
Fixes to allow cached BluetoothRemoteGATTCharacteristic to work with 2v14.14 onwards (>1 central)
|
||||||
|
|
|
@ -5,11 +5,11 @@
|
||||||
);
|
);
|
||||||
|
|
||||||
var log = function(text, param){
|
var log = function(text, param){
|
||||||
|
if (global.showStatusInfo)
|
||||||
|
showStatusInfo(text)
|
||||||
if (settings.debuglog){
|
if (settings.debuglog){
|
||||||
var logline = new Date().toISOString() + " - " + text;
|
var logline = new Date().toISOString() + " - " + text;
|
||||||
if (param){
|
if (param) logline += ": " + JSON.stringify(param);
|
||||||
logline += " " + JSON.stringify(param);
|
|
||||||
}
|
|
||||||
print(logline);
|
print(logline);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
var addNotificationHandler = function(characteristic) {
|
var addNotificationHandler = function(characteristic) {
|
||||||
log("Setting notification handler: " + supportedCharacteristics[characteristic.uuid].handler);
|
log("Setting notification handler"/*supportedCharacteristics[characteristic.uuid].handler*/);
|
||||||
characteristic.on('characteristicvaluechanged', (ev) => supportedCharacteristics[characteristic.uuid].handler(ev.target.value));
|
characteristic.on('characteristicvaluechanged', (ev) => supportedCharacteristics[characteristic.uuid].handler(ev.target.value));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -61,7 +61,8 @@
|
||||||
writeCache(cache);
|
writeCache(cache);
|
||||||
};
|
};
|
||||||
|
|
||||||
var characteristicsFromCache = function() {
|
var characteristicsFromCache = function(device) {
|
||||||
|
var service = { device : device }; // fake a BluetoothRemoteGATTService
|
||||||
log("Read cached characteristics");
|
log("Read cached characteristics");
|
||||||
var cache = getCache();
|
var cache = getCache();
|
||||||
if (!cache.characteristics) return [];
|
if (!cache.characteristics) return [];
|
||||||
|
@ -75,6 +76,7 @@
|
||||||
r.properties = {};
|
r.properties = {};
|
||||||
r.properties.notify = cached.notify;
|
r.properties.notify = cached.notify;
|
||||||
r.properties.read = cached.read;
|
r.properties.read = cached.read;
|
||||||
|
r.service = service;
|
||||||
addNotificationHandler(r);
|
addNotificationHandler(r);
|
||||||
log("Restored characteristic: ", r);
|
log("Restored characteristic: ", r);
|
||||||
restored.push(r);
|
restored.push(r);
|
||||||
|
@ -141,7 +143,7 @@
|
||||||
src: "bthrm"
|
src: "bthrm"
|
||||||
};
|
};
|
||||||
|
|
||||||
log("Emitting HRM: ", repEvent);
|
log("Emitting HRM", repEvent);
|
||||||
Bangle.emit("HRM", repEvent);
|
Bangle.emit("HRM", repEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +157,7 @@
|
||||||
if (battery) newEvent.battery = battery;
|
if (battery) newEvent.battery = battery;
|
||||||
if (sensorContact) newEvent.contact = sensorContact;
|
if (sensorContact) newEvent.contact = sensorContact;
|
||||||
|
|
||||||
log("Emitting BTHRM: ", newEvent);
|
log("Emitting BTHRM", newEvent);
|
||||||
Bangle.emit("BTHRM", newEvent);
|
Bangle.emit("BTHRM", newEvent);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -257,8 +259,8 @@
|
||||||
var buzzing = false;
|
var buzzing = false;
|
||||||
var onDisconnect = function(reason) {
|
var onDisconnect = function(reason) {
|
||||||
log("Disconnect: " + reason);
|
log("Disconnect: " + reason);
|
||||||
log("GATT: ", gatt);
|
log("GATT", gatt);
|
||||||
log("Characteristics: ", characteristics);
|
log("Characteristics", characteristics);
|
||||||
retryTime = initialRetryTime;
|
retryTime = initialRetryTime;
|
||||||
clearRetryTimeout();
|
clearRetryTimeout();
|
||||||
switchInternalHrm();
|
switchInternalHrm();
|
||||||
|
@ -273,13 +275,13 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
var createCharacteristicPromise = function(newCharacteristic) {
|
var createCharacteristicPromise = function(newCharacteristic) {
|
||||||
log("Create characteristic promise: ", newCharacteristic);
|
log("Create characteristic promise", newCharacteristic);
|
||||||
var result = Promise.resolve();
|
var result = Promise.resolve();
|
||||||
// For values that can be read, go ahead and read them, even if we might be notified in the future
|
// For values that can be read, go ahead and read them, even if we might be notified in the future
|
||||||
// Allows for getting initial state of infrequently updating characteristics, like battery
|
// Allows for getting initial state of infrequently updating characteristics, like battery
|
||||||
if (newCharacteristic.readValue){
|
if (newCharacteristic.readValue){
|
||||||
result = result.then(()=>{
|
result = result.then(()=>{
|
||||||
log("Reading data for " + JSON.stringify(newCharacteristic));
|
log("Reading data", newCharacteristic);
|
||||||
return newCharacteristic.readValue().then((data)=>{
|
return newCharacteristic.readValue().then((data)=>{
|
||||||
if (supportedCharacteristics[newCharacteristic.uuid] && supportedCharacteristics[newCharacteristic.uuid].handler) {
|
if (supportedCharacteristics[newCharacteristic.uuid] && supportedCharacteristics[newCharacteristic.uuid].handler) {
|
||||||
supportedCharacteristics[newCharacteristic.uuid].handler(data);
|
supportedCharacteristics[newCharacteristic.uuid].handler(data);
|
||||||
|
@ -289,8 +291,8 @@
|
||||||
}
|
}
|
||||||
if (newCharacteristic.properties.notify){
|
if (newCharacteristic.properties.notify){
|
||||||
result = result.then(()=>{
|
result = result.then(()=>{
|
||||||
log("Starting notifications for: ", newCharacteristic);
|
log("Starting notifications", newCharacteristic);
|
||||||
var startPromise = newCharacteristic.startNotifications().then(()=>log("Notifications started for ", newCharacteristic));
|
var startPromise = newCharacteristic.startNotifications().then(()=>log("Notifications started", newCharacteristic));
|
||||||
if (settings.gracePeriodNotification > 0){
|
if (settings.gracePeriodNotification > 0){
|
||||||
log("Add " + settings.gracePeriodNotification + "ms grace period after starting notifications");
|
log("Add " + settings.gracePeriodNotification + "ms grace period after starting notifications");
|
||||||
startPromise = startPromise.then(()=>{
|
startPromise = startPromise.then(()=>{
|
||||||
|
@ -301,7 +303,7 @@
|
||||||
return startPromise;
|
return startPromise;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return result.then(()=>log("Handled characteristic: ", newCharacteristic));
|
return result.then(()=>log("Handled characteristic", newCharacteristic));
|
||||||
};
|
};
|
||||||
|
|
||||||
var attachCharacteristicPromise = function(promise, characteristic) {
|
var attachCharacteristicPromise = function(promise, characteristic) {
|
||||||
|
@ -312,11 +314,11 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
var createCharacteristicsPromise = function(newCharacteristics) {
|
var createCharacteristicsPromise = function(newCharacteristics) {
|
||||||
log("Create characteristics promise: ", newCharacteristics);
|
log("Create characteristics promis ", newCharacteristics);
|
||||||
var result = Promise.resolve();
|
var result = Promise.resolve();
|
||||||
for (var c of newCharacteristics){
|
for (var c of newCharacteristics){
|
||||||
if (!supportedCharacteristics[c.uuid]) continue;
|
if (!supportedCharacteristics[c.uuid]) continue;
|
||||||
log("Supporting characteristic: ", c);
|
log("Supporting characteristic", c);
|
||||||
characteristics.push(c);
|
characteristics.push(c);
|
||||||
if (c.properties.notify){
|
if (c.properties.notify){
|
||||||
addNotificationHandler(c);
|
addNotificationHandler(c);
|
||||||
|
@ -328,10 +330,10 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
var createServicePromise = function(service) {
|
var createServicePromise = function(service) {
|
||||||
log("Create service promise: ", service);
|
log("Create service promise", service);
|
||||||
var result = Promise.resolve();
|
var result = Promise.resolve();
|
||||||
result = result.then(()=>{
|
result = result.then(()=>{
|
||||||
log("Handling service: " + service.uuid);
|
log("Handling service" + service.uuid);
|
||||||
return service.getCharacteristics().then((c)=>createCharacteristicsPromise(c));
|
return service.getCharacteristics().then((c)=>createCharacteristicsPromise(c));
|
||||||
});
|
});
|
||||||
return result.then(()=>log("Handled service" + service.uuid));
|
return result.then(()=>log("Handled service" + service.uuid));
|
||||||
|
@ -368,7 +370,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
promise = promise.then((d)=>{
|
promise = promise.then((d)=>{
|
||||||
log("Got device: ", d);
|
log("Got device", d);
|
||||||
d.on('gattserverdisconnected', onDisconnect);
|
d.on('gattserverdisconnected', onDisconnect);
|
||||||
device = d;
|
device = d;
|
||||||
});
|
});
|
||||||
|
@ -379,14 +381,14 @@
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
promise = Promise.resolve();
|
promise = Promise.resolve();
|
||||||
log("Reuse device: ", device);
|
log("Reuse device", device);
|
||||||
}
|
}
|
||||||
|
|
||||||
promise = promise.then(()=>{
|
promise = promise.then(()=>{
|
||||||
if (gatt){
|
if (gatt){
|
||||||
log("Reuse GATT: ", gatt);
|
log("Reuse GATT", gatt);
|
||||||
} else {
|
} else {
|
||||||
log("GATT is new: ", gatt);
|
log("GATT is new", gatt);
|
||||||
characteristics = [];
|
characteristics = [];
|
||||||
var cachedId = getCache().id;
|
var cachedId = getCache().id;
|
||||||
if (device.id !== cachedId){
|
if (device.id !== cachedId){
|
||||||
|
@ -404,7 +406,10 @@
|
||||||
|
|
||||||
promise = promise.then((gatt)=>{
|
promise = promise.then((gatt)=>{
|
||||||
if (!gatt.connected){
|
if (!gatt.connected){
|
||||||
var connectPromise = gatt.connect(connectSettings);
|
log("Connecting...");
|
||||||
|
var connectPromise = gatt.connect(connectSettings).then(function() {
|
||||||
|
log("Connected.");
|
||||||
|
});
|
||||||
if (settings.gracePeriodConnect > 0){
|
if (settings.gracePeriodConnect > 0){
|
||||||
log("Add " + settings.gracePeriodConnect + "ms grace period after connecting");
|
log("Add " + settings.gracePeriodConnect + "ms grace period after connecting");
|
||||||
connectPromise = connectPromise.then(()=>{
|
connectPromise = connectPromise.then(()=>{
|
||||||
|
@ -432,7 +437,7 @@
|
||||||
|
|
||||||
promise = promise.then(()=>{
|
promise = promise.then(()=>{
|
||||||
if (!characteristics || characteristics.length === 0){
|
if (!characteristics || characteristics.length === 0){
|
||||||
characteristics = characteristicsFromCache();
|
characteristics = characteristicsFromCache(device);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -445,11 +450,11 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
characteristicsPromise = characteristicsPromise.then((services)=>{
|
characteristicsPromise = characteristicsPromise.then((services)=>{
|
||||||
log("Got services:", services);
|
log("Got services", services);
|
||||||
var result = Promise.resolve();
|
var result = Promise.resolve();
|
||||||
for (var service of services){
|
for (var service of services){
|
||||||
if (!(supportedServices.includes(service.uuid))) continue;
|
if (!(supportedServices.includes(service.uuid))) continue;
|
||||||
log("Supporting service: ", service.uuid);
|
log("Supporting service", service.uuid);
|
||||||
result = attachServicePromise(result, service);
|
result = attachServicePromise(result, service);
|
||||||
}
|
}
|
||||||
if (settings.gracePeriodService > 0) {
|
if (settings.gracePeriodService > 0) {
|
||||||
|
@ -496,7 +501,7 @@
|
||||||
log("Power off for " + app);
|
log("Power off for " + app);
|
||||||
if (gatt) {
|
if (gatt) {
|
||||||
if (gatt.connected){
|
if (gatt.connected){
|
||||||
log("Disconnect with gatt: ", gatt);
|
log("Disconnect with gatt", gatt);
|
||||||
try{
|
try{
|
||||||
gatt.disconnect().then(()=>{
|
gatt.disconnect().then(()=>{
|
||||||
log("Successful disconnect");
|
log("Successful disconnect");
|
||||||
|
|
|
@ -42,12 +42,20 @@ function draw(y, type, event) {
|
||||||
if (event.energy) str += " kJoule: " + event.energy.toFixed(0);
|
if (event.energy) str += " kJoule: " + event.energy.toFixed(0);
|
||||||
g.setFontVector(12).drawString(str,px,y+60);
|
g.setFontVector(12).drawString(str,px,y+60);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var firstEventBt = true;
|
var firstEventBt = true;
|
||||||
var firstEventInt = true;
|
var firstEventInt = true;
|
||||||
|
|
||||||
|
|
||||||
|
// This can get called for the boot code to show what's happening
|
||||||
|
function showStatusInfo(txt) {
|
||||||
|
var R = Bangle.appRect;
|
||||||
|
g.reset().clearRect(R.x,R.y2-24,R.x2,R.y2).setFont("6x8");
|
||||||
|
txt = g.wrapString(txt, R.w)[0];
|
||||||
|
g.setFontAlign(0,1).drawString(txt, (R.x+R.x2)/2, R.y2);
|
||||||
|
}
|
||||||
|
|
||||||
function onBtHrm(e) {
|
function onBtHrm(e) {
|
||||||
if (firstEventBt){
|
if (firstEventBt){
|
||||||
clear(24);
|
clear(24);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"id": "bthrm",
|
"id": "bthrm",
|
||||||
"name": "Bluetooth Heart Rate Monitor",
|
"name": "Bluetooth Heart Rate Monitor",
|
||||||
"shortName": "BT HRM",
|
"shortName": "BT HRM",
|
||||||
"version": "0.10",
|
"version": "0.11",
|
||||||
"description": "Overrides Bangle.js's build in heart rate monitor with an external Bluetooth one.",
|
"description": "Overrides Bangle.js's build in heart rate monitor with an external Bluetooth one.",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"type": "app",
|
"type": "app",
|
||||||
|
|
Loading…
Reference in New Issue