Andreas Rozek
[ Impressum ]   [ Datenschutzerklärung ]   [ Kontakt ]   [ ]

Kommunikation mit Uhr von Webseiten aus

Bangle.js Kommunikation mit Uhr von Webseiten aus

Genauso wie die Espruino IDE mit einer gekoppelten Bangle.js kommuniziert, kann es auch jede andere Webseite machen - der Schlüssel dazu ist das JavaScript-Modul Puck.js.

Nach dem Einbinden von

<script src="http://www.puck-js.com/puck.js"></script>

in ein Web-Dokument stehen folgende Methoden zur Verfügung:

  • connect - stellt eine explizite Bluetooth-Verbindung zu einer Uhr her
  • isConnected - liefert true, falls eine Uhr (implizit) über Bluetooth verbunden ist
  • getConnection - liefert eine bestehende (implizite) Bluetooth-Verbindung zu einer Uhr
  • close - schließt die (implizite) Bluetooth-Verbindung zur Uhr
  • write - sendet Anweisungen auf eine Uhr (über eine implizite Verbindung)
  • eval - führt Anweisungen auf einer Uhr aus & liefert das Ergebnis (über implizite Vbdg.)
  • setTime - setzt Zeit und Zeitzone auf einer Uhr (über eine implizite Verbindung)
  • modal
Nota bene: damit Puck.js funktionieren kann, müssen sowohl der Browser als auch das verwendete Endgerät (Desktop, Tablet, Smartphone) WebBluetooth unterstützen!

WebBluetooth-Erkennung

Das folgende Skript ist eine vereinfachte Version der WebBT-Erkennung aus Puck.js:

  function WebBTisSupported () {
if (
(navigator.platform.indexOf('Win') >= 0) && (
(navigator.userAgent.indexOf("Chrome/54") >= 0) ||
(navigator.userAgent.indexOf("Chrome/55") >= 0) ||
(navigator.userAgent.indexOf("Chrome/56") >= 0)
)
) { return false }

return (navigator.bluetooth != null);
}

.

Leider funktioniert diese Erkennung nicht vollständig: es kann sehr wohl passieren, dass eine Unterstützung von Bluetooth angezeigt wird, aufgrund einer Benutzereinstellung aber trotzdem nicht verfügbar ist (der Opera-Browser ist solch ein Kandidat).

Nur der Anzeige, dass WebBT nicht unterstützt wird, kann stets vertraut werden.

Kommunikation über implizite Verbindungen

Die Kommunikation mit einer Bangle.js kann über eine explizit hergestellte Verbindung geschehen - oder über eine implizite Verbindung, die von Puck.js selbst verwaltet wird.

Letzteres ist einfacher, ersteres bietet mehr Kontrolle über die Kommunikation.

Eine implizite Verbindung wird von Puck.js automatisch hergestellt, sobald (zu Beginn oder nach dem Schließen einer vorherigen impliziten Verbindung) eine der Methoden write, eval oder setTime aufgerufen wird.

Verschicken von Anweisungen (write)

Die "Kommunikation mit einer Uhr" spielt sich genauso ab wie der Umgang mit dem Terminal-Fenster der Espruino-IDE.

Puck.write(text, callback) verschickt den gegebenen Text, als hätte man ihn in den Terminal-Bereich eingetippt und ruft anschließend die callback-Funktion mit der Terminal-Ausgabe als einzigem Argument auf.

Puck.write(`
function drawPacMan () {
Bangle.setLCDMode('80x80');
g.clear();
g.setColor(1,1,0);
var Image = Graphics.createImage(` ****\\n******\\n******\\n **\\n******\\n ****`);
g.drawImage(Image, 37,37);
g.flip();
}
drawPacMan();
`, function (Output) {
console.log(Output)
});

würde folgende Ausgabe

>function drawPacMan () {
: Bangle.setLCDMode('80x80');
: g.clear();
: g.setColor(1,1,0);
: var Image = Graphics.createImage(' ****\n******\n******\n **\n******\n ****');
: g.drawImage(Image, 37,37);
: g.flip();
:};
=function () { ... }
>drawPacMan();
=undefined
>

in die Browser-Konsole schreiben.

Sofern noch keine Verbindung zu einer Uhr besteht, wird eine solche von Puck.js selbst hergestellt.

Auswertung von Ausdrücken (eval)

Die Funktion Puck.eval(expression, callback) schickt den durch expression gegebenen JavaScript-Ausdruck an die angeschlossene Uhr, wertet ihn dort aus und ruft anschließend die als callback mitgegebene Funktion mit dem in einen JavaScript-Wert umgewandelten Ergebnis als einzigem Argument auf.

Puck.eval('Math.sin(30*Math.PI/180)', function (Result) {
console.log('Result = ' + Result);
console.log('Result is a ' + typeof Result);
});

würde

Result = 0.5
Result is a number

in die Browser-Konsole schreiben.

Datum, Zeit und Zeitzone setzen (setTime)

Die Funktion Puck.setTime(callback) setzt Datum, Zeit und Zeitzone einer angeschlossenen Uhr auf die Werte, die gerade auf dem Browser-Endgerät gelten.

Puck.setTime(function (Response) {
console.log(Response);
});

würde etwas Ähnliches wie

setTime(1578815998.802);if (E.setTimeZone) E.setTimeZone(1);
=undefined
>

in die Konsole des Browsers schreiben - und natürlich die Uhr entsprechend konfigurieren.

Implizite Verbindung schließen (close)

Falls die Verbindung zur Uhr nicht automatisch geschlossen wird (z.B. weil eine andere Anwendung Verbindung zur selben Uhr aufgenommen hat) kann sie auch gezielt geschlossen werden:

Puck.close();

Kommunikation über explizite Verbindungen

Auf Wunsch kann die Verbindung zu einer Bangle.js aber auch selbst verwaltet werden - z.B. wenn mehrere Uhren vorhanden sind und Verbindungen zu allen Uhren unterhalten werden sollen.

Explizite Verbindung zu einer Uhr herstellen

Sobald das Modul Puck.js geladen ist, kann eine explizite Verbindung zu einer Bangle.js hergestellt werden:

Puck.connect((Connection) => {
if (Connection == null) {
console.error('no WebBT connection established');
} else {
console.log('WebBT connection is ready to be used');
}
});

Sofern Ihr Browser WebBT unterstützt, können Sie dieses Skript gleich ausprobieren:

Verbindung zu einer Uhr belauschen

Sobald die Verbindung zu einer Uhr besteht, kann sie mithilfe von Event-Routinen "belauscht" werden - auf diese Weise können z.B. Teile einer grafischen Benutzerschnittstelle deaktiviert werden, sobald eine Verbindung zusammenbricht.

Folgende Events werden von einer Verbindung gefeuert:

  • open - informiert über die erfolgte Verbindungsaufnahme
  • data - informiert über empfangene Daten
  • close - informiert über das Beenden einer Verbindung
Puck.connect((Connection) => {
if (Connection == null) {
console.error('no WebBT connection established');

Connection.on('open', () => { handle connection establishment });
Connection.on('data', (received) => { handle incoming data });
Connection.on('close', () => { handle connection termination });
} else {
console.log('WebBT connection is ready to be used');
}
});

Mit einer Uhr kommunizieren

Für die Kommunikation über eine explizite Verbindung steht nur die Methode write zur Verfügung - diese funktioniert ähnlich wie ihr zuvor beschriebenes Pendant für implizite Verbindungen, ist aber an das Objekt einer expliziten Verbindung gebunden:

connection.write(text,callback);

Das folgende Beispiel bildet die für implizite Verbindungen beschriebene Funktion setTime für explizite Verbindungen nach:

let now = new Date();
connection.write(
'\x10setTime(' + (now.getTime()/1000) + '); E.setTimeZone(' + (now.getTimezoneOffset()/-60) + ')\n',
function (Output) {
alert('function has been completed');
}
);

Verbindung zu einer Uhr beenden

Eine bestehende Verbindung kann mittels

connection.close();

wieder geschlossen werden.