How to see if device is Connected - javascript

I have an application that I used to connect to external devices through Bluetooth, using the BLE-PLX library.
I have a problem during the scan and connect, because not always it works.
This is the code that I use to connect one device through Bluetooth:
// First Scan
scans1() {
this.manager.startDeviceScan(null, null, (error, device) => {
if (error) {
this.manager.stopDeviceScan();
console.log("0.Error, retry connection.")
this.scans1()
//return;
}
if ((device.name == this.model_dx(this.props.Model)) || (device.name == this.model_sx(this.props.Model)))
{
this.manager.stopDeviceScan();
console.log("1.Device Founded - ", device.name)
this.setState({device1: device})
this.manager.connectToDevice(device.id)
.then(() => {
console.log("2.Launch Scans 2") // this is for connect to the second device.
this.scan2();
})
.catch(() => {
Alert.alert("Error " + "Connection Failed.");
Actions.homepage();
})
}
else if ((device.name == null )) {
this.manager.stopDeviceScan();
console.log("3.Device is - null - retry scan")
this.scans1();
} else {
this.manager.stopDeviceScan();
console.log("4.Error: Device not found.")
Actions.homepage();
}
});
Now what I would to know, how can I see if a device is connected or not? ( I don't know if could be another kind of error, I have tried to resolve any kind of problem).
Following the guide they said:
Check connection state of a Device.
isDeviceConnected(deviceIdentifier: DeviceId): Promise<boolean>
Parameters
deviceIdentifier (DeviceId) Device identifier.
Returns
Promise<boolean>:
Promise which emits true if device is connected, and false otherwise.
But I don't understand how can I use it.

I found the solution:
I can use:
this.manager.isDeviceConnected(device.id).then((res) => console.log(res))

Related

How to read BLE Peripheral Characteristics in react native using react-native-ble-plx

I'm developing an application which scans for BLE devices(Peripherals), then connect to them, read their services and characteristics. For now, I was able to connect to an iPhone which acting as a Peripheral device with certain characteristics and also was able to connect to Fitbit Versa Watch to read the heart sensor data. Although I was able to discover their services, I wasn't able to extract more information from the services like ServiceUUId and their characteristics.
Below is my code is written in react native.
scanAndConnect() {
console.log("Scanning Started");
this.manager.startDeviceScan(null, null, (error, device) => {
if (error) {
// Handle error (scanning will be stopped automatically)
console.log("Error in scanning devices:", error);
return
}
// Check if it is a device you are looking for based on advertisement data
// or other criteria.
console.log("Detected Device Details:", device.id, device.name);
// ||device.localName === 'BLEPeripheralApp')
if (device.name === 'Versa Lite'){ //
// Stop scanning as it's not necessary if you are scanning for one device.
console.log("Device Found, Stopping the Scan.");
console.log("Connecting to:",device.name)
this.manager.stopDeviceScan();
device.connect()
.then((device) => {
// this.info("Discovering services and characteristics")
console.log("Connected...Discovering services and characteristics");
return device.discoverAllServicesAndCharacteristics()
})
.then((device) => {
console.log('Services and characteristics discovered');
//return this.testChar(device)
const services = device.services()
console.log(services);
return device.readCharacteristicForService(services)
// device.readCharacteristicForService("abbaff00-e56a-484c-b832-8b17cf6cbfe8")
// this.info("Setting notifications")
//return this.setupNotifications(device)
})
.then(() => {
const characteristicsData = device.readCharacteristicForService();
console.log(characteristicsData);
//this.info("Listening...")
}, (error) => {
console.warn(error.message);
// this.error(error.message)
})
}
});
}
How do I extract the serviceUUId from the Service method and also read the characteristics of that service? For my iPhone peripheral, I have two mutable characteristics that I should be able to read and write.
How do I read them from service to characteristics to the real value?
Any help/suggestions are much appreciated.
Thanks.
You're missing the method characteristicsForService.
Loop over all the services, get their characteristics by
await device.discoverAllServicesAndCharacteristics();
const services = await device.services();
services.forEach(async service => {
const characteristics = await device.characteristicsForService(service.uuid);
characteristics.forEach(console.log);
});

`result.isCancelled` + `result.postId` always undefined after cancellation via ShareDialog on Android

I am attempting to utilize the ShareDialog export from the 'react-native-fbsdk' library.
Our implementation (shown below) works perfectly well when the user doesn't have Facebook installed on their device and when they successfully share their photo.
However, when the user begins to share and discards the Facebook window, result.isCancelled is only captured on iOS. result.postId isn't populated on either iOS and Android.
Is there something that needs to be done in order for result.isCancelled to be populated on Android and/or result.postId to be populated on either platform?
ShareDialog.canShow(shareContent).then(
(canShow) => {
if (canShow) {
return ShareDialog.show(shareContent);
} else {
return false;
}
},
).then(
(result) => {
if (!result) {
Alert.alert('Error', 'You must have Facebook installed on this device in order to share this post')
} else if (result.isCancelled) {
Alert.alert('Cancelled', 'Share cancelled');
} else {
Alert.alert('Success!', 'Share successful');
}
},
(error) => {
Alert.alert(`Share fail with error: ${error}`);
},
)

Error getting PushManager Subscription - JavaScript

I've got the following code that registers a service worker and asks the user allow notifications. I'm getting an error after the user allows the push notifications where the promise returned by serviceWorkerRegistration.pushManager.getSubscription() is null. When I close the browser and force this function call again, it works without errors. I don't understand why. Here is my code:
window.vapidPublicKey = new Uint8Array([4, 45, ...]);
if (navigator.serviceWorker) {
navigator.serviceWorker.register('/serviceworker.js')
.then(function(reg) {
console.log('Service worker change, registered the service worker');
});
}
// Otherwise, no push notifications :(
else {
console.error('Service worker is not supported in this browser');
}
navigator.serviceWorker.ready.then((serviceWorkerRegistration) => {
console.log("ready");
serviceWorkerRegistration.pushManager
.subscribe({
userVisibleOnly: true,
applicationServerKey: window.vapidPublicKey
});
});
// application.js
// Let's check if the browser supports notifications
if (!("Notification" in window)) {
console.error("This browser does not support notifications.");
}
// Let's check whether notification permissions have already been granted
else if (Notification.permission === "granted") {
console.log("Permission to receive notifications has been granted");
}
// Otherwise, we need to ask the user for permission
else if (Notification.permission !== 'denied') {
Notification.requestPermission(function (permission) {
// If the user accepts, let's create a notification
if (permission === "granted") {
console.log("Permission to receive notifications has been granted");
saveSubscriptionToDatabase();
}
});
}
function saveSubscriptionToDatabase(){
navigator.serviceWorker.ready
.then((serviceWorkerRegistration) => {
console.log(serviceWorkerRegistration.pushManager.getSubscription());
serviceWorkerRegistration.pushManager.getSubscription()
.then((subscription) => {
$.post("/users/save_subscription", { subscription: subscription.toJSON() });
});
});
}
The error:
Uncaught (in promise) TypeError: Cannot read property 'toJSON' of null
at serviceWorkerRegistration.pushManager.getSubscription.then
UPDATE:
So I added the following button:
<input type="button" onclick="saveSubscriptionToDatabase();" value="test">
All of the JS and post request works as expected as long as I call the function from the button click but when I call it from the conditional that checks the permission state, it still fails just like before.
UPDATE 2:
I've tried writing the code again but from a different angle.
function registerServiceWorker() {
return navigator.serviceWorker.register('serviceworker.js')
.then(function(registration) {
console.log('Service worker successfully registered.');
return registration;
})
.catch(function(err) {
console.error('Unable to register service worker.', err);
});
}
function askPermission() {
return new Promise(function(resolve, reject) {
const permissionResult = Notification.requestPermission(function(result) {
resolve(result);
});
if (permissionResult) {
permissionResult.then(resolve, reject);
}
})
.then(function(permissionResult) {
if (permissionResult !== 'granted') {
throw new Error('We weren\'t granted permission.');
}
});
}
function subscribeUserToPush() {
return navigator.serviceWorker.register('serviceworker.js')
.then(function(registration) {
const subscribeOptions = {
userVisibleOnly: true,
applicationServerKey: new Uint8Array("key goes here")
};
return registration.pushManager.subscribe(subscribeOptions);
})
.then(function(pushSubscription) {
console.log("never called");
console.log('Received PushSubscription: ', JSON.stringify(pushSubscription));
return pushSubscription;
});
}
registerServiceWorker();
askPermission();
subscribeUserToPush();
The last part of the command chain in subscribeUserToPush() where I have console.log("never called"); never executes and has no errors. I'm testing this in Chrome 67. I am positive that registration.pushManager.subscribe(subscribeOptions); is called.
So after hours of trying different things I finally figured out the problem and it was annoyingly simple. So each time you call navigator.serviceWorker.register('serviceworker.js') you must put a / before the file name. The service worker will register just fine without the / but grabbing the subscription will fail. The examples that you find in the documentation do not include the /.
So, the code should've looked like this:
navigator.serviceWorker.register('/serviceworker.js')
Tada now it works....

Send data using react-native-ble-plx package

In order to realize a project of connected objects. I need to implement a Bluetooth connection between the various devices.
Here, the goal is to create an application in React Native and then send data from this application to my Raspberry. This Raspberry has a connected HC-08 module that takes care of Bluetooth communication.
Now, I would like to use react-native-ble-plx library to send data through Bluetooth. I'm able to connect my Android to the module. But I don't understand how to send data ...
Here's my code :
constructor() {
super()
this.manager = new BleManager()
}
componentWillMount() {
console.log("mounted")
const subscription = this.manager.onStateChange((state) => {
if (state === 'PoweredOn') {
this.scanAndConnect();
subscription.remove();
}
}, true);
}
scanAndConnect() {
this.manager.startDeviceScan(null, null, (error, device) => {
if (error) {
// Handle error (scanning will be stopped automatically)
return
}
console.log(device.name)
// Check if it is a device you are looking for based on advertisement data
// or other criteria.
if (device.name === 'SH-HC-08') {
// Stop scanning as it's not necessary if you are scanning for one device.
this.manager.stopDeviceScan();
console.log(`Found ${device.name}`)
this.setState({
device: device
})
// Proceed with connection.
device.connect()
.then((device) => {
console.log(device)
return device.discoverAllServicesAndCharacteristics()
})
.then((device) => {
console.log(device)
})
.then((result) => {
// Do work on device with services and characteristics
//console.log(this.manager.characteristicsForService("00001800-0000-1000-8000-00805f9b34fb"))
console.log(result)
console.log("connected")
})
.catch((error) => {
// Handle errors
console.log(error)
});
}
});
}
send() {
this.manager.writeCharacteristicWithResponseForDevice("58:7A:62:4F:EF:6D",
this.device.serviceUUIDs[0],
this.manager.characteristicsForDevice(this.device.id),
"ok")
.catch((error) => {
console.log('error in writing data');
console.log(error);
})
}
I would like to have a send method that will send data whenever I want to. But I don't really understand how it works :/
Could someone help me or even give me an example ? I would be really appreciated.
Best regards.
I had success implementing the following:
scanAndConnect() {
this.manager.startDeviceScan(null, null, (error, device) => {
this.info("Scanning...");
console.log(device);
if (error) {
this.error(error.message);
return
}
if (device.name ==='MyDevice') {
this.info("Connecting to Tappy");
this.manager.stopDeviceScan();
device.connect()
.then((device) => {
this.info("Discovering services and characteristics");
return device.discoverAllServicesAndCharacteristics()
})
.then((device) => {
this.info(device.id);
device.writeCharacteristicWithResponseForService('12ab', '34cd', 'aGVsbG8gbWlzcyB0YXBweQ==')
.then((characteristic) => {
this.info(characteristic.value);
return
})
})
.catch((error) => {
this.error(error.message)
})
}
});
Where I use 12ab, insert the UUID of your BLE service. Similarly, where I use 34cd, insert the UUID of your BLE characteristic. Lastly, include a base64 encoding of whatever message you're trying to send where I have aGVsbG8gbWlzcyB0YXBweQ==.
Hope this helps.

Javascript- Web Bluetooth API GATT Error: Not supported

This question might have been asked by many people, but I have no luck to get answer from researching.
My ultimately plan is running a web app with Web Bluetooth API in smartphone with FLIC button to control audios to play. One click, play one audio.
I'm testing the program in my MAC laptop with my iPhoneX first, because I'm thinking if I can get both of them connected, then when I run the web app in smartphone, then I can connect to the FLIC button.
However, I got this error.
Something went wrong. NotSupportedError: GATT Error: Not supported.
Am I missing something? I saw someone mentioned iPhone cannot connect Latop, hopefully this is not true
Below is the code:
$("#bluetooth").on("click", function(){
const controlServiceUUID = '00001805-0000-1000-8000-00805f9b34fb'; // Full UUID
const commandCharacteristicUUID = '00002a0f-0000-1000-8000-00805f9b34fb'; //
var myCharacteristic;
navigator.bluetooth.requestDevice({
acceptAllDevices: true,
optionalServices: [controlServiceUUID]
})
.then(device => {
console.log("Got device name: ", device.name);
console.log("id: ", device.id);
return device.gatt.connect();
console.log("Here");
})
.then(server => {
serverInstance = server;
console.log("Getting PrimaryService");
return server.getPrimaryService(controlServiceUUID);
})
.then(service => {
console.log("Getting Characteristic");
return service.getCharacteristic(commandCharacteristicUUID);
})
.then(characteristic => {
// 0x01,3,0x02,0x03,0x01
myCharacteristic = characteristic;
return myCharacteristic.startNotifications().then(_ => {
log('Notifications started');
myCharacteristic.addEventListener('characteristicvaluechanged', test);
});
})
.catch(function(error) {
console.log("Something went wrong. " + error);
});
function test(event) {
if (myCharacteristic) {
myCharacteristic.startNotifications()
.then(_ => {
console.log("Notification stopped!");
})
.catch(error => {
console.log("Argh!" + error);
});
}
}
});
Web Bluetooth API is only available on ChromeOS and Android 6 or later with flag option.
(https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API)
Different platforms are at different points in implementation. I have been using this repo for updates on the status of the API:
WebBluetoothCG/web-bluetooth
Note the lack of support for ios
Not sure if this fixes your problem (i'm working on muse eeg), but one "hack" to get rid of this error is to wait some time (e.g. 500ms) after each characteristic write. Most platforms don't support write responses yet and writing multiple commands in parallel will cause this error.
https://github.com/WebBluetoothCG/web-bluetooth/blob/master/implementation-status.md
Is your command characteristic UUID filled in incorrectly? Try replacing it with one that can be written?
const controlServiceUUID = 0xfff0; // Full UUID
const commandCharacteristicUUID = 0xfff4; //

Categories