1

我正在尝试通过 BLE 将 LogBook 数据传输到我的应用程序。这适用于 JSON,数据似乎准确。但由于 JSON 编码,它需要一些时间。获取 SBEM 数据要快得多。但我找不到任何关于编码的文档。我发现“内容”字符串是 Base64 编码的。它以 SBEM 开头,这意味着它是未压缩的,如下所述:

https://bitbucket.org/suunto/movesense-device-lib/src/5bcf0b40644a17d48977cf011ebcf6191650c6f0/MovesenseCoreLib/resources/movesense-api/mem/logbook.yaml?fileviewer=file-view-default#lines-186

但我找不到其他任何东西。

有人对此有更多信息或发现编码是什么样的吗?

最好的问候亚历克斯

4

1 回答 1

0

首先澄清一下:当从MDS/Logbook/服务请求 JSON 日志时,数据本身以 SBEM 格式从 Movesense 传感器传输,并在手机上执行转换。如果您有特定示例,其中所述转换很慢(很可能是),最好将 bitbucket 问题添加到 movesense-mobile-lib。

关于 SBEM 格式。这是用于呈现 xml(以及现在的 json)文件的“Suunto Oy 内部”二进制格式。这意味着随着格式的发展,对它的解释可能会发生变化。撇开这个警告不谈,格式如下:

  • 数据以 ID(1-2 字节)、长度(1-4 字节)和内容的块编码
  • 由两个单独的部分组成:描述符和数据,可以在单独的“文件”中(如在日志服务中)
  • 描述符描述数据块中数据的格式(“格式字符串”)
  • 数据块包含所描述格式的二进制数据。

如果您想了解 DataLogger / Logbook 服务使用的 SBEM 格式,请参阅构建期间创建的“生成/sbem-code”文件夹。

最后,这是一个用于解析 SBEM 格式的简单 Python 代码:

from __future__ import print_function

import sys
import re

import glob, os

data_path = sys.argv[0]
descriptor_path = sys.argv[1]

ReservedSbemId_e_Escape = b"\255"
ReservedSbemId_e_Descriptor = 0

#print("data_path:",data_path)
print("descriptor_path:",descriptor_path)

# reads sbem ID upto uint16 from file
def readId(f):
    byte1 = f.read(1)
    id = None
    if not byte1:
        print("EOF found")
    elif byte1 < ReservedSbemId_e_Escape:
        id = int.from_bytes(byte1, byteorder='little')
        #print("one byte id:", id)
    else:
        # read 2 following bytes
        id_bytes = f.read(2)
        id = int.from_bytes(id_bytes, byteorder='little')         
        #print("two byte id:",id)
    return id

# reads sbem length upto uint32 from file
def readLen(f):
    byte1 = f.read(1)
    if byte1 < ReservedSbemId_e_Escape:
        datasize = int.from_bytes(byte1, byteorder='little')
        #print("one byte len:", len)

    else:
        # read 4 following bytes
        id_bytes = f.read(4)
        datasize = int.from_bytes(id_bytes, byteorder='little')         
        #print("4 byte len:",len)
    return datasize

# read sbem chunkheader from file
def readChunkHeader(f):
    id = readId(f)
    if id is None:
        return (None,None)

    datasize = readLen(f)
    ret = (id, datasize)
    print("SBEM chunk header:", ret)
    print(" offset:", f.tell())
    return ret

def readHeader(f):
    # read header
    header_bytes = f.read(8)
    print("SBEM Header: ", header_bytes)

def parseDescriptorChunk(data_bytes):
    print("parseDescriptorChunk data:", chunk_bytes)
    return

def parseDataChunk(data_bytes):
    print("parseDataChunk data:", chunk_bytes)
    return

# read descriptors
with open(descriptor_path, 'rb') as f_desc:

    readHeader(f_desc)

    while True:
        (id, datasize) = readChunkHeader(f_desc)
        if id is None:
#            print("None id:",id)
            break;
        chunk_bytes = f_desc.read(datasize)
        if (len(chunk_bytes) != datasize):
            print("ERROR: too few bytes returned.")
            break

        if id == ReservedSbemId_e_Descriptor:
            parseDescriptorChunk(chunk_bytes)                      
        else:
            print("WARNING: data chunk in descriptor file!")
            parseDataChunk(chunk_bytes)



# read data
with open(data_path, 'rb') as f_data:

    readHeader(f_data)

    while True:
        (id, datasize) = readChunkHeader(f_data)
        if id is None:
#            print("None id:",id)
            break;
        chunk_bytes = f_data.read(datasize)
        if (len(chunk_bytes) != datasize):
            print("ERROR: too few bytes returned.")
            break

        if id == ReservedSbemId_e_Descriptor:
            parseDescriptorChunk(chunk_bytes)                      
        else:
            parseDataChunk(chunk_bytes)

完全免责声明:我为 Movesense 团队工作

于 2018-10-26T05:21:28.917 回答