转:Web Bluetooth 入门简介 API

导读:本篇文章讲解 转:Web Bluetooth 入门简介 API,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

借助 Progressive Web Apps,您现在可以使用 Web 构建成熟的应用程序。由于大量的新规范和功能,我们可以在 Web 上完成您过去需要为其编写本机应用程序的事情。然而,到目前为止,与硬件设备对话仍然是一座遥不可及的桥梁。多亏了 WebBluetooth,我们现在可以构建可以控制灯光、驾驶汽车甚至控制无人机的 PWA。

借助 Progressive Web Apps,Web 越来越接近原生应用程序。但是,具有网络固有的额外好处,例如隐私和跨平台兼容性。

传统上,Web 非常擅长与网络上的服务器通信,特别是与 Internet 上的服务器通信。现在 Web 正在向应用程序发展,我们还需要原生应用程序具有的相同功能。

过去几年在浏览器中实现的新规范和功能的数量是惊人的。我们已经制定了处理 3D 的规范,例如 WebGL 和即将推出的 WebGPU。我们可以流式传输和生成音频、观看视频并将网络摄像头用作输入设备。我们还可以使用 WebAssembly 以几乎原生的速度运行代码。此外,尽管最初是一种仅限网络的媒体,但网络已经转向由服务人员提供的离线支持。

这很好,但有一个领域几乎是原生应用程序的专属领域:与设备通信。这是我们长期以来一直试图解决的问题,而且每个人都可能在某一时刻遇到过。网络非常适合与服务器交谈,但不适用于与设备交谈。例如,考虑尝试在您的网络中设置路由器。您可能必须输入 IP 地址并通过纯 HTTP 连接使用 Web 界面,而没有任何安全性。那只是糟糕的体验和糟糕的安全性。最重要的是,您如何知道正确的 IP 地址是什么?

 

当我们尝试创建一个尝试与设备对话的渐进式 Web 应用程序时,HTTP 也是我们遇到的第一个问题。PWA 仅支持 HTTPS,本地设备始终只是 HTTP。您需要一个 HTTPS 证书,并且为了获得证书,您需要一个具有域名的公开可用的服务器(我说的是我们本地网络上无法访问的设备)。

因此,对于许多设备,您需要原生应用程序来设置和使用设备,因为原生应用程序不受 Web 平台的限制,可以为用户提供愉快的体验。但是,我不想下载一个 500 MB 的应用程序来做到这一点。也许您拥有的设备已经使用了几年,并且该应用程序从未更新为在您的新手机上运行。也许您想使用台式机或笔记本电脑,而制造商只构建了一个移动应用程序。也不是理想的体验。

WebBluetooth 是一种已在 Chrome 和三星 Internet中实施的新规范,它允许我们从浏览器直接与蓝牙低功耗设备进行通信。渐进式 Web 应用程序与 WebBluetooth 相结合,提供 Web 应用程序的安全性和便利性,并具有直接与设备对话的能力。

由于范围有限、音频质量差和配对问题,蓝牙的名声很差。但是,几乎所有这些问题都已成为过去。低功耗蓝牙是一种现代规范,除了使用相同的频谱之外,与旧蓝牙规范几乎没有关系。每天有超过 1000 万台设备支持蓝牙。这包括电脑和手机,还包括心率和血糖监测仪等各种设备、灯泡等物联网设备以及遥控汽车和无人机等玩具。

无聊的理论部分 #

由于蓝牙本身不是一种网络技术,它使用了一些我们可能不熟悉的词汇。因此,让我们回顾一下蓝牙的工作原理和一些术语。

每个蓝牙设备要么是“中央设备”(Central device),要么是“外围设备”( Peripheral )。只有中央设备可以发起通信,并且只能与外围设备通信。中央设备的一个示例是计算机或移动电话。

外围设备无法启动通信,只能与中央设备通信。此外,外围设备只能同时与一个中央设备通信。外围设备不能与另一个外围设备通信。

转:Web Bluetooth 入门简介 API

中央设备可以与多个外围设备通信。

中央设备可以同时与多个外围设备通信,并且可以根据需要中继消息。因此,心率监测器无法与您的灯泡通信,但是,您可以编写一个在中央设备上运行的程序,该程序接收您的心率并在心率超过某个阈值时将灯变为红色。

当我们谈论 WebBluetooth 时,我们谈论的是蓝牙规范的一个特定部分,称为 Generic Attribute Profile,它有一个非常明显的缩写 GATT。(显然,GAP 已经被采用了。)

在 GATT 的上下文中,我们不再谈论中央设备和外围设备,而是客户端和服务器。你的灯泡是服务器。这可能看起来违反直觉,但如果你仔细想想,它实际上是有道理的。灯泡提供服务,即光。就像浏览器连接到 Internet 上的服务器一样,您的手机或计算机是一个客户端,连接到灯泡中的 GATT 服务器。

每台服务器都提供一项或多项服务。其中一些服务是标准的正式一部分,但您也可以定义自己的服务。对于心率监测器,规范中定义了官方服务。就灯泡而言,没有,几乎每个制造商都试图重新发明轮子。每个服务都有一个或多个特征。每个特征都有一个可以读取或写入的值。现在,最好将其视为一个对象数组,每个对象都有具有值的属性。

转:Web Bluetooth 入门简介 API

服务和特征的简化层次结构。

与对象的属性不同,服务和特征不是由字符串标识的。每个服务和特性都有一个唯一的 UUID,它可以是 16 位或 128 位长。正式地,16 位 UUID 是为官方标准保留的,但几乎没有人遵循该规则。最后,每个值都是一个字节数组。蓝牙中没有花哨的数据类型。

蓝牙灯泡项目了解 #

上码:

通过WebBluetooth控制蓝牙灯项目源码: GitHub – BluetoothRocks/Lightbulb: Controlling a lightbulb with WebBluetoothControlling a lightbulb with WebBluetooth. Contribute to BluetoothRocks/Lightbulb development by creating an account on GitHub.转:Web Bluetooth 入门简介 APIhttps://github.com/BluetoothRocks/Lightbulb

演示效果Video:

Web应用也可以连接各种蓝牙设备了:灯、玩具车、LED、无人机…_哔哩哔哩_bilibilihttps://vimeo.com/303045191使用Web Bluetooth,Web应用也可以控制各种蓝牙设备了:灯、玩具车、LED、无人机…转:Web Bluetooth 入门简介 APIhttps://www.bilibili.com/video/av249350269

通过上面初步了解,让我们看一个实际的蓝牙设备:Mipow Playbulb Sphere。您可以使用 BLE Scanner 或 nRF Connect 等应用程序连接到设备并查看所有服务和特征。在这种情况下,我使用的是适用于 iOS 的 BLE Scanner 应用程序。

当您连接到灯泡时,您首先看到的是服务列表。有一些标准化的,如设备信息服务和电池服务。但也有一些定制服务。我对 16 位 UUID 的服务特别感兴趣0xff0f。如果你打开这个服务,你可以看到一长串特征。我不知道这些特征中的大多数是做什么的,因为它们仅由 UUID 标识,并且不幸的是它们是自定义服务的一部分;它们没有标准化,制造商也没有提供任何文件。

UUID 的第一个特征0xfffc似乎特别有趣。它有四个字节的值。如果我们将这些字节的值从 更改0x000000000x00ff0000,灯泡会变成红色。将其更改为0x0000ff00将灯泡变为绿色和0x000000ff蓝色。这些是 RGB 颜色,与我们在 HTML 和 CSS 中使用的十六进制颜色完全对应。

第一个字节有什么作用?好吧,如果我们将值更改为0xff000000,灯泡会变成白色。灯泡包含四个不同的 LED,通过更改四个字节中每个字节的值,我们可以创建我们想要的每种颜色。


WebBluetooth API  #

我们可以使用本机应用程序来更改灯泡的颜色真是太棒了,但是我们如何从浏览器中做到这一点呢?原来,有了我们刚刚学到的蓝牙和GATT的知识,这要感谢WebBluetooth API,还是比较简单的。只需要几行 JavaScript 就可以改变灯泡的颜色。

让我们回顾一下 WebBluetooth API。

连接到设备 #

我们需要做的第一件事是从浏览器连接到设备。我们调用该函数navigator.bluetooth.requestDevice()并为该函数提供一个配置对象。该对象包含有关我们想要使用的设备以及我们的 API 应该可以使用哪些服务的信息。

在以下示例中,我们过滤设备名称,因为我们只想查看PLAYBULB名称中包含前缀的设备。我们还将指定0xff0f为我们要使用的服务。由于该requestDevice()函数返回一个Promise,我们可以等待结果。

let device = await navigator.bluetooth.requestDevice({
    filters: [
        { namePrefix: 'PLAYBULB' }
    ],
    optionalServices: [ 0xff0f ]
});

No filters的话可以参考下面的写法,可以把周边包含battery_service的BLE设备显示出来:
navigator.bluetooth.requestDevice({
  acceptAllDevices: true,
  optionalServices: [‘battery_service’] // Required to access service later.
})
.then(device => { /* … */ })
.catch(error => { console.error(error); });

当我们调用此函数时,会弹出一个窗口,其中包含符合我们指定过滤器的设备列表。现在我们必须手动选择要连接的设备。这是安全和隐私的重要步骤,并为用户提供控制权。用户决定是否允许 Web 应用程序连接,当然还决定允许连接到哪个设备。如果用户不手动选择设备,Web 应用程序无法获取设备列表或连接。

转:Web Bluetooth 入门简介 API

用户必须通过选择设备手动连接。

访问设备后,我们可以通过调用设备属性上的connect()函数连接到 GATT 服务器gatt并等待结果。

let server = await device.gatt.connect();

一旦我们有了服务器,我们就可以getPrimaryService()使用我们想要使用的服务的 UUID 作为参数调用服务器并等待结果。

let service = await server.getPrimaryService(0xff0f);

然后getCharacteristic()以特征的 UUID 作为参数调用服务并再次等待结果。

我们现在有了可以用来写入和读取数据的特征:

let characteristic = await service.getCharacteristic(0xfffc);

注意:

如果不清楚 getPrimaryService 的参数,那么可以首先用 getPrimaryServices 函数获取服务的 uuid,注意这个函数后面有个s字母。getPrimaryServices 返回一个服务数组,每个数组元素有 uuid 属性。可以这样操作:

server.getPrimaryService(server.getPrimaryServices()[0].uuid)。

getCharacteristic 也一样,可以用 getCharacteristics() 函数获取所有特性的 uuid,注意s字母。


读数据:characteristic.readValue() 读取的数据不对,一定要用以下接口:

characteristic.addEventListener( 'characteristicvaluechanged') 

写入数据 characteristic.writeValue() #

要写入数据,我们可以writeValue()在特征上调用函数,将我们要写入的值作为ArrayBuffer,这是一种二进制数据的存储方式。我们不能使用正则数组的原因是正则数组可以包含各种类型的数据,甚至可以有空洞。

由于我们无法直接创建或修改 ArrayBuffer,因此我们使用“类型化数组”来代替。类型化数组的每个元素总是相同的类型,并且没有任何漏洞。在我们的例子中,我们将使用Uint8Array,它是无符号的,因此它不能包含任何负数;一个整数,所以它不能包含分数;它是 8 位,只能包含 0 到 255 之间的值。换句话说:字节数组。

characteristic.writeValue(
    new Uint8Array([ 0, r, g, b  ])
);

我们已经知道这个特殊的灯泡是如何工作的。我们必须提供四个字节,每个 LED 一个。每个字节都有一个介于 0 和 255 之间的值,在这种情况下,我们只想使用红色、绿色和蓝色 LED,因此我们将白色 LED 关闭,使用值 0。

发送:数据量大的包是否一次性发完?还是拆分发?

读取数据 ReadValue() #

要读取灯泡的当前颜色,我们可以使用该readValue()函数并等待结果。

let value = await characteristic.readValue();

let r = value.getUint8(1);
let g = value.getUint8(2);
let b = value.getUint8(3);

我们返回的值是一个 ArrayBuffer 的 DataView,它提供了一种从 ArrayBuffer 中获取数据的方法。在我们的例子中,我们可以使用getUint8()带有索引的函数作为参数来从数组中提取单个字节。

获得变更通知 特征值-Notify  #

最后,还有一种方法可以在设备的值发生变化时得到通知。这对于蓝牙灯泡项目来说并不是很有用,但对于我们的心率监测器项目来说是必要的。我们心率的值是不断变化的,我们不想每秒钟手动轮询当前

打开Notify功能:characteristic.startNotifications(),只需要打开一次, 后面所有的数据都可以通过监听事件收到 。

characteristic.addEventListener(
    'characteristicvaluechanged', e => {
        let r = e.target.value.getUint8(1);
        let g = e.target.value.getUint8(2);
        let b = e.target.value.getUint8(3);
    }
);

characteristic.startNotifications();

要在值更改时获取回调,我们必须addEventListener()使用参数characteristicvaluechanged和回调函数调用特征上的函数。每当值发生变化时,都会以事件对象为参数调用回调函数,我们可以从事件目标的 value 属性中获取数据。最后,再次从 ArrayBuffer 的 DataView 中提取单个字节。

由于蓝牙网络的带宽有限,我们不得不通过调用startNotifications()特性来手动启动这个通知机制。否则,网络将被不必要的数据淹没。此外,由于这些设备通常使用电池,因此我们不必发送的每个字节都将最终提高设备的电池寿命,因为不需要经常打开内部无线电。

结论 #

我们现在已经完成了 90% 以上的 WebBluetooth API。只需几个函数调用并发送 4 个字节,您就可以创建一个控制BLE灯泡颜色的 Web 应用程序。如果再添加几行代码,您甚至可以控制玩具车或驾驶无人机。随着越来越多的蓝牙设备进入市场,可能性是无穷无尽的。

更多资源 #

提示 #

在 Chrome 浏览器地址栏输入: about://bluetooth-internals
 可查看蓝牙内部页面,以便您可以检查附近蓝牙设备的所有信息:状态、服务、特征和描述符。

转:Web Bluetooth 入门简介 API

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/101617.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!