Commit 3b1b5a2f authored by Donald Chen's avatar Donald Chen
Browse files

Merge branch 'fix/ES-542' into 'master'

ES-542

See merge request !1
parents cba91305 6a361c40
......@@ -4,89 +4,109 @@
* A Device object manages an edge device and its bluetooth communication
*/
class Device {
constructor(bleDevice) {
this.id = bleDevice.address.replace(/:/g, '');
this.bleDevice = bleDevice;
this.fwVersion = null;
}
constructor(bleDevice) {
this.id = bleDevice.address.replace(/:/g, '');
this.bleDevice = bleDevice;
this.fwVersion = null;
this.timer = null;
}
/**
* Returns a Promise that will resolve with the ble device's firmware revision,
* or reject with an error
*/
readFirmware() {
return new Promise((resolve, reject) => {
console.log(`${this.id}: readFirmwareRevision`);
this.bleDevice.readFirmwareRevision((error, firmwareRevision) => {
if (error) {
reject(error);
return;
}
resetState() {
this.fwVersion = null;
this.timer = null;
}
console.log(`${this.id}: firmware revision = ${firmwareRevision}`);
this.fwVersion = firmwareRevision;
/**
* Returns a Promise that will resolve with the ble device's firmware revision,
* or reject with an error
*/
readFirmware() {
return new Promise((resolve, reject) => {
console.log(`${this.id}: readFirmwareRevision`);
this.bleDevice.readFirmwareRevision((error, firmwareRevision) => {
if (error) {
reject(error);
return;
}
resolve();
});
});
}
console.log(`${this.id}: firmware revision = ${firmwareRevision}`);
this.fwVersion = firmwareRevision;
/**
* Returns a Promise that will connect and set up the ble device with noble.
* Once set up, it will read the device's firmware and enable its luxometer.
*/
setUp() {
return new Promise((resolve, reject) => {
this.bleDevice.connectAndSetUp((setupError) => {
if (setupError) {
reject(new Error(setupError));
}
resolve();
});
});
}
this.readFirmware()
.then(this.enableLuxometer.bind(this))
.then(() => {
resolve(this);
})
.catch((err) => {
console.log(`DEVICE SETUP ERROR: ${err}`);
throw err;
});
});
});
}
/**
* Returns a Promise that will connect and set up the ble device with noble.
* Once set up, it will read the device's firmware and enable its luxometer.
*/
setUp() {
return new Promise((resolve, reject) => {
/**
* Returns a Promise that will enable the device's luxometer
*/
enableLuxometer() {
return new Promise((resolve) => {
console.log(`${this.id}: enableLuxometer`);
this.bleDevice.enableLuxometer(resolve);
});
}
this.timer = setTimeout(() => {
this.bleDevice.disconnect();
reject("connection timeout")
}, 10000)
/**
* Returns a Promise that will notify the device's luxometer
*/
notifyLuxometer() {
return new Promise((resolve) => {
console.log(`${this.id}: notifyLuxometer`);
this.bleDevice.notifyLuxometer(resolve);
});
}
this.bleDevice.connectAndSetUp((setupError) => {
if (setupError) {
reject(new Error(setupError));
}
/**
* This function will bind its given callback to run when the ble device
* triggers a 'luxometerChange' event.
*/
onLuxometerChange(callback) {
console.log(`${this.id}: set up onluxchange`);
this.bleDevice.on('luxometerChange', (lux) => {
callback(this, lux);
});
if(this.timer == null) {
this.bleDevice.disconnect();
reject("connection timeout")
} else {
clearTimeout(this.timer)
this.timer = null
}
return this.notifyLuxometer();
}
this.readFirmware()
.then(this.enableLuxometer.bind(this))
.then(() => {
resolve(this);
})
.catch((err) => {
console.log(`DEVICE SETUP ERROR: ${err}`);
reject(err)
});
});
});
}
/**
* Returns a Promise that will enable the device's luxometer
*/
enableLuxometer() {
return new Promise((resolve) => {
console.log(`${this.id}: enableLuxometer`);
this.bleDevice.enableLuxometer(resolve);
});
}
/**
* Returns a Promise that will notify the device's luxometer
*/
notifyLuxometer() {
return new Promise((resolve) => {
console.log(`${this.id}: notifyLuxometer`);
this.bleDevice.notifyLuxometer(resolve);
});
}
/**
* This function will bind its given callback to run when the ble device
* triggers a 'luxometerChange' event.
*/
onLuxometerChange(callback) {
console.log(`${this.id}: set up onluxchange`);
this.bleDevice.on('luxometerChange', (lux) => {
callback(this, lux);
});
return this.notifyLuxometer();
}
}
module.exports = Device;
module.exports = Device;
\ No newline at end of file
......@@ -20,62 +20,82 @@ const devices = {};
const provider = new CloudProvider(config);
function startScanning() {
// Restart scanning
// https://github.com/sandeepmistry/noble/issues/223
if (noble.state === 'poweredOn') {
noble.startScanning();
} else {
throw new Error('BLE poweredOff');
}
// Restart scanning
// https://github.com/sandeepmistry/noble/issues/223
if (noble.state === 'poweredOn') {
noble.startScanning([], true);
} else {
throw new Error('BLE poweredOff');
}
}
function stopScanning() {
noble.stopScanning();
}
/**
* Called when a new device is discovered
*/
var connected = false
function onDiscover(beaconInst) {
const device = new Device(beaconInst);
// Ignore duplicates
if (devices[device.id]) {
console.log(`${device.id}: Duplicate device found, ignoring`);
startScanning();
return;
}
console.log(`Discovered: ${device.id}`);
// Connect to device and setup
device.setUp()
.then(() => {
device.onLuxometerChange((d, lux) => {
const telemetry = {
deviceID: d.id,
light: lux.toFixed(1),
};
provider.sendTelemetry(telemetry);
});
// Wait for as long as possible before scanning again to avoid race
// conditions
startScanning();
// Store in list of known devices
devices[device.id] = device;
// Set disconnect handler
device.bleDevice.on('disconnect', function onDc() {
console.log(`${device.id}: disconnected`);
delete devices[device.id];
device.bleDevice.removeListener('disconnect', onDc);
});
});
const id = beaconInst.address.replace(/:/g, '');
if (connected) {
return
}
var device = null;
// must reuse device objects!
if (devices[id]) {
device = devices[id]
} else {
device = new Device(beaconInst);
}
console.log(`Connecting: ${device.id}`);
//must stop scanning to initiate a connection
connected = true
stopScanning()
// Connect to device and setup
device.setUp()
.then(() => {
device.onLuxometerChange((d, lux) => {
const telemetry = {
deviceID: d.id,
light: lux.toFixed(1),
};
provider.sendTelemetry(telemetry);
});
// Store in list of known devices
devices[device.id] = device;
// Set disconnect handler
device.bleDevice.on('disconnect', function disconnectHandler() {
console.log(`${device.id}: disconnected`);
device.bleDevice.removeListener('disconnect', disconnectHandler);
device.resetState();
connected = false
startScanning();
});
})
.catch((error) => {
console.log(error)
device.bleDevice.disconnect();
connected = false
startScanning();
});
}
noble.on('scanStop', () => {
console.log('Scanning stopped');
console.log('Scanning stopped');
});
noble.on('scanStart', () => {
console.log('Scanning started');
console.log('Scanning started');
});
rigadoSensorBeacon.discoverAll(onDiscover);
......@@ -11,7 +11,7 @@
"dependencies": {
"dateformat": "^2.0.0",
"firehoser": "^1.2.4",
"noble": "^1.8.1",
"noble-device": "^1.4.1"
"noble": "1.8.1",
"noble-device": "1.4.1"
}
}
......@@ -38,7 +38,16 @@ const rigadoSensorBeacon = function (peripheral) {
// TODO: the local name and uuid may need to be configureable
rigadoSensorBeacon.is = function (peripheral) {
return (peripheral.advertisement.localName === 'EvalDemo' || peripheral.uuid === BMDEVAL_UUID_SERVICE);
var result = false
if( peripheral
&& peripheral.advertisement
&& (peripheral.advertisement.localName == 'EvalDemo'
|| peripheral.advertisement.serviceUuids.includes(BMDEVAL_UUID_SERVICE))) {
result = true
}
return result
};
NobleDevice.Util.inherits(rigadoSensorBeacon, NobleDevice);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment