Eddystone example using Javascript library
Introduction
Eddystone is a Bluetooth Low Energy beacon profile released by Google. Here is an example of how you can setup the BleuIO to advertise an URL as an Eddystone beacon.
First create an Html file called index.html, where you can see the output.
<!DOCTYPE html>
<html lang="en">
<head>
<title>BleuIO - Eddystone beacon</title>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
crossorigin="anonymous"
/>
</head>
<body>
<div class="container-md mt-5">
<div class="row">
<div class="page-header">
<h1>BleuIO - <small>Eddystone beacon</small></h1>
</div>
</div>
<div class="row mt-5 p-0">
<div id="buttonRow" class="d-flex justify-content-left">
<div class="d-flex p-1">
<button type="button" id="connectButton" class="btn btn-success">
Connect
</button>
</div>
<div class="d-flex p-1">
<button
type="button"
id="eddystoneButton"
class="btn btn-success disabled"
>
Create an Eddystone beacon
</button>
</div>
<div class="d-flex p-1">
<h6 class="m-2">URL:</h6>
<input
type="text"
id="urlInputField"
class="form-control"
style="width: 451px;"
value="0d:16:aa:fe:10:00:03:67:6f:6f:67:6c:65:07"
/>
</div>
</div>
</div>
<div class="row mt-5">
<div class="col-md-12">
<h5>Output:</h5>
<p id="output"></p>
</div>
</div>
</div>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
crossorigin="anonymous"
></script>
<script src="script.js"></script>
</body>
</html>
Now create a js file called script.js and paste the following code.
import * as my_dongle from 'bleuio'
import 'regenerator-runtime / runtime'
// Works the first time I drive
// If I stop it and try to start again, nothing happens
// After trying to insert a sleep () after at_advdata () (line 108)
// does it work to run it over and over again
// The dongles I have work differently when I run this.
// If I run two instances of the program and run the same sequences
// the results are still different.
// On the marked dongle I can start a beacon once (if I do not use sleep ())
// so it can not start again if I have stopped it.
// On the unmarked dongle I can start a beacon but not turn it off
const output = document.querySelector ("# output");
const connectButton = document.querySelector ('# connectButton');
const eddystoneButton = document.querySelector ('# eddystoneButton');
const urlInputField = document.querySelector ('# urlInputField');
let connected = false;
let advertising = false;
/ **
* Connects / disconnects the dongle
* /
const handleConnect = async () => {
if (! connected) {
connect ();
} else {
disconnect ();
}
}
connectButton.addEventListener ('click', handleConnect);
/ **
* Connects the dongle via the computers COM port
* Prompts the user to choose port from dialog in chrome
* Enables the button to start the beacon
* /
const connect = async () => {
// Connect to dongle
await my_dongle.at_connect ();
connectButton.textContent = 'Disconnect';
output.textContent = 'Connected to dongle';
connected = true;
// Enable the eddystone button which is disabled by default to avoid errors
eddystoneButton.addEventListener ('click', handleEddystone);
eddystoneButton.classList.remove ('disabled');
}
/ **
* Stops advertising the URL and disconnects the dongle
* and disables the button to start the beacon
* /
const disconnect = async () => {
// Stops advertising
await my_dongle.at_advstop ();
// Disconnects the dongle
await my_dongle.at_disconnect ();
// Reset dongle status
connected = false;
advertising = false;
output.textContent = 'Dongle disconnected';
// Disable the eddystone button to avoid errors
eddystoneButton.removeEventListener ('click', handleEddystone);
eddystoneButton.classList.add ('disabled')
eddystoneButton.textContent = 'Create an Eddystone beacon';
connectButton.textContent = 'Connect';
}
/ **
* Starts / stops advertising the URL
* /
const handleEddystone = async () => {
// If the dongle is not advertising, start advertising
if (! advertising) {
startAdvertising ();
} else {
stopAdvertising ();
}
}
/ **
* Starts advertising the eddystone url
* /
const startAdvertising = async () => {
// Disable the eddyStoneButton until the advertising has completed
eddystoneButton.classList.add ('disabled');
// A prefix is needed for the dongle to advertise the data as an Eddystone Beacon
// Note that a whitespace at the end is required
const beaconPrefix = '03: 03: aa: fe '
// Sets the data to advertise the provided url in the html will advertise "https://google.com"
await my_dongle.at_advdata (beaconPrefix + urlInputField.value);
// Start advertising
await my_dongle.at_advstart ();
advertising = true;
output.textContent = 'Eddystone beacon created';
eddystoneButton.textContent = 'Stop';
eddystoneButton.classList.remove ('disabled');
}
/ **
* Stops the dongle from advertising
* /
const stopAdvertising = async () => {
// Stops advertising
await my_dongle.at_advstop ();
advertising = false;
output.textContent = 'Eddystone beacon stopped';
eddystoneButton.textContent = 'Create an Eddystone beacon'
}
Now open the index.html file in a browser and select the COM port for BleuIO dongle.
Full source also available on GitHub.