Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-connection to already known hubs #114

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions examples/web_bluetooth.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,10 @@ div {
margin-bottom: 10px;
}

div#current_color {
position: absolute;
top: 61px;
left: 120px;
}

div#color {
border: 1px solid #666666;
width: 20px;
height: 20px;
position: absolute;
top: -4px;
left: 92px;
}

table td {
Expand Down
28 changes: 23 additions & 5 deletions examples/web_bluetooth.html
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@
const hubs = poweredUP.getHubs(); // Get an array of all connected hubs
document.getElementById("color").style.backgroundColor = PoweredUP.Consts.ColorNames[color];
hubs.forEach(async (hub) => {
const led = await hub.waitForDeviceByType(PoweredUP.Consts.DeviceType.HUB_LED);
led.setColor(color); // Set the color
const led = await hub.waitForDeviceByType(PoweredUP.Consts.DeviceType.HUB_LED);
led.setColor(color); // Set the color
})
color++;
if (color > 10) {
Expand All @@ -82,7 +82,23 @@

const scan = function () {
if (PoweredUP.isWebBluetooth) {
poweredUP.scan(); // Start scanning for hubs
poweredUP.scan(); // Start scanning for known hubs
} else {
alert("Your browser does not support the Web Bluetooth specification.");
nathankellenicki marked this conversation as resolved.
Show resolved Hide resolved
}
}

const stop = function () {
if (PoweredUP.isWebBluetooth) {
poweredUP.stop(); // Stop scanning for known hubs
} else {
alert("Your browser does not support the Web Bluetooth specification.");
nathankellenicki marked this conversation as resolved.
Show resolved Hide resolved
}
}

const requestDevice = function () {
if (PoweredUP.isWebBluetooth) {
poweredUP.requestDevice(); // Start scanning for new hubs
} else {
alert("Your browser does not support the Web Bluetooth specification.");
}
Expand All @@ -99,9 +115,11 @@
<body>
<div><h1>Web Bluetooth node-poweredup Example</h1></div>
<div>
<a class="button" href="#" onclick="scan();">Add new Hub</a>
<a class="button" href="#" onclick="scan();">Scan for known hubs</a>
<a class="button" href="#" onclick="stop();">Stop scan</a>
<a class="button" href="#" onclick="requestDevice();">Add new hub</a>
</div>
<div id="current_color">
<div>
<span>Current Color: </span><div id="color">&nbsp;</div>
</div>
<div>
Expand Down
95 changes: 91 additions & 4 deletions src/poweredup-browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ export class PoweredUP extends EventEmitter {


private _connectedHubs: {[uuid: string]: BaseHub} = {};
private _scan: boolean = false;
private _pendingDevices: BluetoothDevice[] = [];


constructor () {
Expand All @@ -35,9 +37,9 @@ export class PoweredUP extends EventEmitter {

/**
* Begin scanning for Powered UP Hub devices.
* @method PoweredUP#scan
* @method PoweredUP#requestDevice
*/
public async scan () {
public async requestDevice () {

try {

Expand All @@ -61,6 +63,10 @@ export class PoweredUP extends EventEmitter {
]
});

if (this._scan) {
this._watchAdvertisements(device);
}

// @ts-ignore
const server = await device.gatt.connect();
this._discoveryEventHandler.call(this, server);
Expand All @@ -73,6 +79,48 @@ export class PoweredUP extends EventEmitter {
}


/**
* Begin scanning for Powered UP Hub devices that were connected before.
* @method PoweredUP#scan
*/
public async scan () {
try {
if (this._scan) {
return true;
}

this._scan = true;
const devices = await navigator.bluetooth.getDevices();

debug("Start watching advertisements");

for (const device of devices) {
this._watchAdvertisements(device);
}

return true;

} catch (err) {
debug(err);
return false;
}
}


/**
* Stop scanning for Powered UP Hub devices.
* @method PoweredUP#stop
*/
public async stop () {
if (!this.scan) {
return true;
}

debug("Stop watching advertisements");
this._scan = false;
return true;
}

/**
* Retrieve a list of Powered UP Hubs.
* @method PoweredUP#getHubs
Expand Down Expand Up @@ -127,6 +175,45 @@ export class PoweredUP extends EventEmitter {
}


private _watchAdvertisements (device: BluetoothDevice) {
if (device.watchingAdvertisements) {
return;
}

device.addEventListener('advertisementreceived', async (event) => {
// Chrome 87 does not support unwatchAdvertisements yet.
if (!this._scan) {
return;
}

// If the connection to the hub was lost, it is not possible
// to re-connect as long as 'connected' is still true.
if (device.gatt === undefined || device.gatt.connected || this._pendingDevices.includes(device)) {
debug('Ignored advertisement from ' + device.id);
return;
}

// Ignore further reconnects for one second.
this._pendingDevices.push(device);

try {
const server = await device.gatt.connect();
debug(device.id + ' connected');
this._discoveryEventHandler.call(this, server);
} catch (err) {
debug(err);
} finally {
setTimeout(() => this._pendingDevices.splice(this._pendingDevices.indexOf(device), 1), 1000);
}
});

device.addEventListener('gattserverdisconnected', async (event) => debug(device.id + ' disconnected'));
device.watchAdvertisements();

debug('Watching advertisements of ' + device.id);
}


private _determineLPF2HubType (device: IBLEAbstraction): Promise<Consts.HubType> {
return new Promise((resolve, reject) => {
let buf: Buffer = Buffer.alloc(0);
Expand Down Expand Up @@ -177,14 +264,14 @@ export class PoweredUP extends EventEmitter {
try {
await device.discoverCharacteristicsForService(Consts.BLEService.WEDO2_SMART_HUB);
hubType = Consts.HubType.WEDO2_SMART_HUB;
// tslint:disable-next-line
// tslint:disable-next-line
} catch (error) {}
try {
if (hubType !== Consts.HubType.WEDO2_SMART_HUB) {
await device.discoverCharacteristicsForService(Consts.BLEService.LPF2_HUB);
isLPF2Hub = true;
}
// tslint:disable-next-line
// tslint:disable-next-line
} catch (error) {}

if (isLPF2Hub) {
Expand Down