Skip to content

Commit

Permalink
Added support for subscribing to and receiving specific events from t… (
Browse files Browse the repository at this point in the history
#7)

* Added support for subscribing to and receiving specific events from the Event Service

* Ensured micro:bit event notifications only subscribed to once. Improved API for subscribing to specific micro:bit events as opposed to whole families

* Changed name of writeEvent to writeClientEvent to be specific about the characteristic to be written to

* Incorporated callback in call to writeClientEventRequirements

* Made arg names more consistent

* Updated API documentation wrt new event-service

* 1. Removed extraneous console.log in lib/event-service.js
2. Renamed subscribeMicrobitEvents to subscribeEvents. Renamed unsubscribeMicrobitEvents to unsubscribeEvents. Renamed associated event id to 'event'.
3. Simplfied writeClientEventRequirements with buffer.writeUInt16Le(value, offset).
4. Made microbit_event_subscribed a member variable of the EventService type
5. Added #include "MicroBit.h" to example microbit source code included in the comments of the example

* Suggestions to #7

Also making styling consistent
  • Loading branch information
bluetooth-martin authored and sandeepmistry committed Dec 15, 2016
1 parent 5015316 commit e9c8930
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 1 deletion.
36 changes: 35 additions & 1 deletion API.md
Expand Up @@ -8,7 +8,8 @@
1. [LED Matrix](#led-matrix)
1. [Magnetometer](#magnetometer)
1. [Temperature](#temperature)
1. [UART](#uart)
1. [UART](#uart)
1. [Event](#event-5)

## Require module

Expand Down Expand Up @@ -368,3 +369,36 @@ microbit.on('uartData', function(data) {
```javascript
microbit.writeUart(data, callback(error));
```

## [Event](https://lancaster-university.github.io/microbit-docs/ble/event-service/)

### Micro:bit Events

Events come in two varieties, reflected by the two corresponding characteristics:

Micro:bit Events emanate from the micro:bit and may be notified to the connected client.

Client Events emanate from the connected client and may be written to the connected micro:bit


### Write event

```javascript
microbit.writeEvent(id, value, callback);
```

### Subscription

```javascript
microbit.subscribeEvents(id, value, callback(error));

microbit.unsubscribeEvent(callback(error));
```

#### Event

```javascript
microbit.on('event', function(id, value) {
// ...
});
```
83 changes: 83 additions & 0 deletions examples/event-listener.js
@@ -0,0 +1,83 @@
/*
* Informs micro:bit of interest in events with event ID 9999 and any event value. Logs events as they are received.
*
* Author: Martin Woolley, @bluetooth_mdw
*
* Example:
*
* sudo node event-listener.js
*
* micro:bit hex file must include the Bluetooth Event Service
*
* http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html for hex files and micro:bit info
*/

var BBCMicrobit = require('../index'); // or require('bbc-microbit')

var EVENT_FAMILY = 9999;
var EVENT_VALUE_ANY = 0;
var EVENT_VALUE_1 = 1;

// search for a micro:bit, to discover a particular micro:bit use:
// BBCMicrobit.discoverById(id, callback); or BBCMicrobit.discoverByAddress(id, callback);
//
// C/C++ code containing the following fragments can be used for testing.
// Pressing button A generates event ID 9999, value 1
// Pressing button B generates event ID 9999, value 2
//

/*
#include "MicroBit.h"
MicroBit uBit;
int EVENT_ID = 9999;
void onButton(MicroBitEvent e)
{
if (e.source == MICROBIT_ID_BUTTON_A) {
MicroBitEvent evt(EVENT_ID, 1);
}
if (e.source == MICROBIT_ID_BUTTON_B) {
MicroBitEvent evt(EVENT_ID, 2);
}
}
int main()
{
// Initialise the micro:bit runtime.
uBit.init();
uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, onButton);
uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, onButton);
release_fiber();
}
*/

console.log('Scanning for microbit');
BBCMicrobit.discover(function(microbit) {
console.log('\tdiscovered microbit: id = %s, address = %s', microbit.id, microbit.address);


microbit.on('event', function(id, value) {
console.log('\ton -> micro:bit event received event: %d value: %d', id, value);
});

microbit.on('disconnect', function() {
console.log('\tmicrobit disconnected!');
process.exit(0);
});

console.log('connecting to microbit');
microbit.connectAndSetUp(function() {
console.log('\tconnected to microbit');

// Example 1: subscribe to all micro:bit events with ID 9999 and any event value
console.log('subscribing to event family 9999, any event value');
microbit.subscribeEvents(EVENT_FAMILY, EVENT_VALUE_ANY, function() {
console.log('\tsubscribed to micro:bit events of required type');
});

// Example 2: subscribe to the specific event with ID=9999 and value=0001 only
// console.log('subscribing to event family 9999, event value 0001');
// microbit.subscribeEvents(EVENT_FAMILY, EVENT_VALUE_1, function() {
// console.log('\tsubscribed to micro:bit events of required type');
// });
});
});
2 changes: 2 additions & 0 deletions lib/bbc-microbit.js
Expand Up @@ -7,6 +7,7 @@ var LedService = require('./led-service');
var MagnetometerService = require('./magnetometer-service');
var TemperatureService = require('./temperature-service');
var UartService = require('./uart-service');
var EventService = require('./event-service');

function BBCMicrobit() {
}
Expand All @@ -30,6 +31,7 @@ NobleDevice.Util.mixin(BBCMicrobit, LedService);
NobleDevice.Util.mixin(BBCMicrobit, MagnetometerService);
NobleDevice.Util.mixin(BBCMicrobit, TemperatureService);
NobleDevice.Util.mixin(BBCMicrobit, UartService);
NobleDevice.Util.mixin(BBCMicrobit, EventService);

BBCMicrobit.prototype.toString = function() {
return JSON.stringify({
Expand Down
60 changes: 60 additions & 0 deletions lib/event-service.js
@@ -0,0 +1,60 @@
var EVENT_SERVICE_SERVICE_UUID = 'e95d93af251d470aa062fa1922dfa9a8';
var MICROBIT_EVENT_CHARACTERISTIC_UUID = 'e95d9775251d470aa062fa1922dfa9a8';
var CLIENT_REQUIREMENTS_CHARACTERISTIC_UUID = 'e95d23c4251d470aa062fa1922dfa9a8';
var CLIENT_EVENT_CHARACTERISTIC_UUID = 'e95d5404251d470aa062fa1922dfa9a8';

var EventService = function() {
};

EventService.prototype.hasEventService = function() {
return this.hasService(EVENTSERVICE_SERVICE_UUID);
};

EventService.prototype.onEvent = function(data) {
if (data.length !== 4) {
return;
}

var id = data.readInt16LE(0);
var value = data.readInt16LE(2);

this.emit('event', id, value);
};

EventService.prototype.subscribeEvents = function(id, value, callback) {
// specifying which events we want to be notified about
this._writeClientEventRequirements(id, value, callback);

if (!this._eventSubscribed) {
this.onEventBinded = this.onEvent.bind(this);

this.subscribeCharacteristic(EVENT_SERVICE_SERVICE_UUID, MICROBIT_EVENT_CHARACTERISTIC_UUID, this.onEventBinded);

this._eventSubscribed = true;
}
};

EventService.prototype.unsubscribeEvent = function(callback) {
// allow this event if not previously explicitly subscribed through a call to subscribeEvents because the micro:bit may have persisted the
// client characteristic configuration descriptor state from a previous "session"
this.unsubscribeCharacteristic(EVENT_SERVICE_SERVICE_UUID, MICROBIT_EVENT_CHARACTERISTIC_UUID, this.onEventBinded, callback);

this._eventSubscribed = false;
};

EventService.prototype._writeClientEventRequirements = function(id, value, callback) {
var data = new Buffer(4);

data.writeUInt16LE(id, 0);
data.writeUInt16LE(value, 2);

this.writeDataCharacteristic(EVENT_SERVICE_SERVICE_UUID, CLIENT_REQUIREMENTS_CHARACTERISTIC_UUID, data, callback);
};

EventService.prototype.writeEvent = function(id, value, callback) {
var data = id << 16 | value;

this.writeUInt32LECharacteristic(EVENT_SERVICE_SERVICE_UUID, CLIENT_EVENT_CHARACTERISTIC_UUID, data, callback);
};

module.exports = EventService;

0 comments on commit e9c8930

Please sign in to comment.