简体   繁体   English

如何使用bleno发布多条BLE特征数据

[英]How do I publish multiple pieces of BLE characteristic data using bleno

I'm trying to learn how to implement a BLE peripheral device using bleno . 我正在尝试学习如何使用bleno实现BLE外围设备。 I would like to discover and read from the peripheral using noble . 我想使用noble发现和阅读外围设备。 For example sake, I want to know how I would implement a simple smart scale that reports back weight, BMI etc following the Weight Measurement GATT spec . 例如,为了方便起见,我想知道如何实现一个简单的智能秤,该秤根据“ 体重测量GATT”规范报告后背重量,BMI等。

What I can't figure out is if reading multiple pieces of information from a characteristic is possible. 我不知道的是,是否可以从特征中读取多个信息。 The Weight Measurement GATT spec makes it seem like in a single noble characteristic.read() you can simultaneously retrieve Weight, BMI, Height etc. 重量测量GATT规范使它看起来像一个单一的高贵characteristic.read() 。read characteristic.read()您可以同时获取体重,体重指数,身高等。

For example, this simple bleno characteristic: 例如,以下简单的布尔诺特性:

'use strict';

const bleno = require('bleno');

const flags = {
  IMPERIAL_WEIGHT: 1 << 0,
  USER_ID_PRESENT: 1 << 2,
  BMI_AND_HEIGHT_PRESENT: 1 << 3
};

module.exports.flags = flags;

module.exports.WeightMeasureCharacteristic = class WeightMeasureCharacteristic extends bleno.Characteristic {
  constructor(scale) {
    super({
      uuid: '2A9D',
      properties: ['read'],
      descriptors: []
    });
    this._scale = scale;
  }

  onReadRequest(offset, callback) {
    //Not sure what `offset` means here or how it gets populated...Help!

    let data = new Buffer.alloc(8); //1(flags)+2(weightImp)+1(userId)+2(BMI)+2(heightImp)

    //Write supported value fields as bit flags
    data.writeUInt8(flags.IMPERIAL_WEIGHT | flags.USER_ID_PRESENT | flags.BMI_AND_HEIGHT_PRESENT), 0);

    //Write out weight (lbs) - offset 1 byte
    data.writeUInt16LE(100.01, 1);

    //Write out user id - offset 12 bytes (flags+Imperial, no need to include offset for SI or Timestamp since the flags indicated those are not supported)
    data.writeUInt8(69, 3);

    //Write out BMI - offset 13 bytes (after UserId)
    data.writeUInt16LE(18.6, 4);

    //Write out Height Imperial - offset 17 bytes (after Height SI)
    data.writeUInt16LE(72.2, 6);

    callback(this.RESULT_SUCCESS, data);
  }
}

If someone was able to implement/pseudocode onReadRequest() above I think it would help things click in my head. 如果有人能够在上面实现/伪代码onReadRequest() ,那将有助于我进入头脑。

Questions: 问题:

  1. Does the C<number> value in the "Field Requirement" column of the spec indicate the offset value passed into onReadRequest() ? 规范的“字段要求”列中的C<number>值是否指示传递给onReadRequest()offset量值? If a consumer wanted to get "Weight - SI"( C1 ) they would somehow construct a noble characteristic.read() that triggers an onReadRequest(1,function()) ? 如果消费者想要获得“ Weight-SI”( C1 ),他们将以某种方式构造一个高贵的characteristic.read()来触发onReadRequest(1,function()) If so, how is the characteristic.read() constructed? 如果是这样, characteristic.read()是如何构造的?
  2. How do I construct a noble characteristic.read() to get the value of the Flags ? 我如何构造一个高贵的characteristic.read()来获取Flags的值?
  3. How do I construct a noble characteristic.read() that will return me multiple (or all) properties in one read? 如何构造一个高贵的characteristic.read() ,使其在一次读取中返回多个(或全部)属性? Ex: Give me all values this peripheral supports (Weight - SI, BMI etc). 例如:给我该外围设备支持的所有值(重量-SI,BMI等)。
  4. If my peripheral supports imperial weight, user id, bmi, and height how do I populate the data for the callback in onReadRequest() . 如果我的外围设备支持英制重量,用户ID,bmi和身高,则如何在onReadRequest()填充回调的data Is what I have above correct? 我上面的内容正确吗?
  5. How is offset populated & what does it mean in onReadRequest(offset,callback) ? 如何offset人口&这是什么意思在onReadRequest(offset,callback)

Or, am I doing this all wrong? 还是我做错了所有? Should I have a characteristic for each value? 每个值都应该有一个特征吗? Ex: a single characteristic for weight - SI, and another characteristic for BMI? 例如:重量的单一特征-SI,而BMI的另一个特征? I would like to avoid this, would prefer to save round trips and get multiple values in one call. 我想避免这种情况,宁愿保存往返行程并在一个调用中获得多个值。

An attempt to answer your question: 尝试回答您的问题:

  1. I am not sure what the C<number> means, but I believe that each field (Weight, BMI, Height, etc.) is represented as a group of one or more octets. 我不确定C<number>是什么意思,但是我相信每个字段(“重量”,“ BMI”,“高度”等)都表示为一组一个或多个八位位组。 Notice how at the bottom of the spec it says 注意规范底部的内容

Note: The fields in the above table are in the order of LSO to MSO. 注意:上表中的字段按LSO到MSO的顺序排列。 Where LSO = Least Significant Octet and MSO = Most Significant Octet. 其中LSO =最低有效八位字节,MSO =最高有效八位字节。

Thus, I believe that in order to get the "Weight - SI" field, you would do something like: 因此,我相信为了获得“ Weight-SI”字段,您可以执行以下操作:

    characteristic.read((err, data) => {
      let char_flags = data.readUint8(0); // read first bit
      if (!(char_flags & flags.IMPERIAL_WEIGHT)) // if SI weight
        let weightSI = data.readUint16LE(1) // read SI weight starting at second bit
    });
  1. Answered above 以上回答
  2. Answered above, just check whether the property exists in the flags and then read the value from the appropriate offset. 上面回答过,只需检查属性是否存在于标志中,然后从适当的偏移量读取值即可。 Also this might help. 同样可能会有所帮助。
  3. Answered above. 以上回答。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM