BluCurrent is an application for 0-20mA sensors. BluCurrent application is versatile in the sense that it can function with the BluCurrent bluetooth adapter as well as the 0-20mA volt sensor on the gateway.
Prerequisites- Familiarity with Javascript, HTML, CSS
- Gateway or BluCurrent adapter
Let's take a look at the blucurrent.js file which acts as the driver for the device. We define a variable BluCurrent which is set the the return of the self induced function. In the function, we define the bluvolt object. You will see that all our drivers follow a similar format when it comes to defining device attributes and functions to interface with.
var SERVICE_UUID = 0x1234;
var SHUNT_VOLT_UUID = 0x1236;
var BUS_VOLT_UUID = 0x1237;
var CURRENT_UUID = 0x1239;
var RELAY_UUID = 0x123B;
We first define UUIDs for our devices services and characteristics. We interact with one service in our application:
SERVICE_UUID is set to the UUID of what we call the current service. It is the parent of four characteristics, one to read shunt voltage, one to read the bus voltage, one to read the current, and lastly to trigger a relay.
The UUID allow us to identify where data is coming from as well as have us right data using the devices Gatt Server.
The file has the following functions defined:
function BlueCurrent(bluetooth)
BluCurrent.prototype.writeData = function writeData(sendData)
We will go over these functions individually. We can see, the functions show what we can do with the device.
The most complex looking function is the connect function. In reality, it's really just a call to connect to the device followed by a series of promises used to gather all the necessary information post-connection.
var self = this;
var options = {filters: [{services: [SERVICE_UUID]}]};
return navigator.bluetooth.requestDevice(options)
First we define the filters to find the device and use the requestDevice call to start scanning. We set the filter to look for devices with the current service UUID. We also create a variable self to hold the reference of the current object as to not lose that reference in a callback function.
.then(function (device) {
self.bluetoothDevice = device;
return device.gatt.connect();
})
Once we get a result, we get the device object from the requestDevice call. We connect to the device that receive.
.then(function (server) {
return server.getPrimaryService(SERVICE_UUID)
})
After connection is complete, we try to get the service with the voltage data.
service.getCharacteristic(RELAY_UUID)
.then(function (characteristic) {
self.relayCharacteristic = characteristic;
return self.relayCharacteristic.readValue()
.then(function (value) {
if (value.getUint8(0) === 0) { //ON
self.relayStatus = true;
} else { //OFF
self.relayStatus = false;
}
});
})
On retrieval of the service, we then setup a Promise.all with to receive each characteristic. For all characteristics, we request the characteristic from the gatt server through the UUID. We then try to read or get notifications and handle accordingly.
return Promise.all([
service.getCharacteristic(CURRENT_UUID)
.then(function (characteristic) {
return characteristic.startNotifications()
.then(function () {
characteristic.addEventListener('characteristicvaluechanged',
function (event) {
//todo: generate event
if (self.updateUI) {
self.updateUI(event.target.value, 'current');
}
}
);
});
}),
service.getCharacteristic(SHUNT_VOLT_UUID)
.then(function (characteristic) {
return characteristic.startNotifications()
.then(function () {
characteristic.addEventListener('characteristicvaluechanged',
function (event) {
//todo: generate event
if (self.updateUI) {
self.updateUI(event.target.value, 'shunt');
}
}
);
});
}),
service.getCharacteristic(BUS_VOLT_UUID)
.then(function (characteristic) {
return characteristic.startNotifications()
.then(function () {
characteristic.addEventListener('characteristicvaluechanged',
function (event) {
//todo: generate event
if (self.updateUI) {
self.updateUI(event.target.value, 'bus');
}
}
);
});
]);
})
First characteristic is the one hosting the current data. We call startNotification with request the device to 'Notify' us on data changes. When we successfully enabled, we set an event listener for the 'characteristicvaluechanged' and pass it a function to handle the event. In that function, we call a updateUI which will send the data to the UI controller to display. We do the same for bus voltage characteristic and the shunt voltage characteristic.
.then(function () {
self.connected = true;
});
Once that is all done, we set our connected flag to true. This can let the application know we are ready.
The remaining functions are fairly simple. All but disconnect being I/O functions with the device.
BluCurrent.prototype.disconnect = function disconnect() {
var self = this;
if (!self.bluetoothDevice) {
return Promise.reject();
}
return self.bluetoothDevice.disconnect()
.then(function () {
self.connected = false;
self.relayCharacteristic = undefined;
self.relayStatus = undefined;
self.bluetoothDevice = undefined;
return Promise.resolve();
});
}
The disconnect function, I assume is very straight forward. If we are not connected, we reject the call. If we are, we call disconnect on that device. The fulfillment of that call clears up any data detrimental to the app to avoid any errors and getting the app properly into a disconnected state.
BluCurrent.prototype.writeData = function writeData(sendData) {
if (this.relayCharacteristic) {
return this.relayCharacteristic.writeValue(sendData);
}
return Promise.reject();
}
Lastly, the writeData function writes to the relay characteristic to trigger a change in the relay.
Comments