Movesense 从 LogBook 解码 SBEM 数据
Movesense decode SBEM data from LogBook
我正在尝试通过 BLE 将 LogBook 数据传输到我的应用程序。
这适用于 JSON,数据似乎准确。
但由于 JSON 编码,它需要时间。
获取 SBEM 数据要快得多。但我找不到任何关于编码的文档。我发现 "Content" 字符串是 Base64 编码的。
它以 SBEM 开头,这意味着它是未压缩的,如下所述:
但我找不到其他任何东西。
是否有人对此有进一步的信息或发现编码是什么样的?
此致
亚历克斯
首先澄清一下:当从 MDS/Logbook/ 服务请求 JSON 日志时,数据本身以 SBEM 格式从 Movesense 传感器传输,并且转换在 phone 上执行。如果您有特定示例,其中所述转换很慢(很可能),最好将 bitbucket 问题添加到 movesense-mobile-lib。
关于 SBEM 格式。这是 "Suunto Oy internal" 二进制格式,用于显示 xml(现在是 json)文件。这意味着随着格式的演变,对它的解释可能会发生变化。抛开这个警告,格式如下:
- 数据被编码成具有 ID(1-2 字节)、长度(1-4 字节)和内容的块
- 由两个独立的部分组成:描述符和数据可以分开 "files"(就像在日志服务中一样)
- 描述符描述数据块中数据的格式("format string")
- 数据块包含描述格式的二进制数据。
如果您想了解 DataLogger/Logbook 服务使用的 SBEM 格式,请参阅构建期间创建的 "generated/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"5"
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 团队工作
我正在尝试通过 BLE 将 LogBook 数据传输到我的应用程序。 这适用于 JSON,数据似乎准确。 但由于 JSON 编码,它需要时间。 获取 SBEM 数据要快得多。但我找不到任何关于编码的文档。我发现 "Content" 字符串是 Base64 编码的。 它以 SBEM 开头,这意味着它是未压缩的,如下所述:
但我找不到其他任何东西。
是否有人对此有进一步的信息或发现编码是什么样的?
此致 亚历克斯
首先澄清一下:当从 MDS/Logbook/ 服务请求 JSON 日志时,数据本身以 SBEM 格式从 Movesense 传感器传输,并且转换在 phone 上执行。如果您有特定示例,其中所述转换很慢(很可能),最好将 bitbucket 问题添加到 movesense-mobile-lib。
关于 SBEM 格式。这是 "Suunto Oy internal" 二进制格式,用于显示 xml(现在是 json)文件。这意味着随着格式的演变,对它的解释可能会发生变化。抛开这个警告,格式如下:
- 数据被编码成具有 ID(1-2 字节)、长度(1-4 字节)和内容的块
- 由两个独立的部分组成:描述符和数据可以分开 "files"(就像在日志服务中一样)
- 描述符描述数据块中数据的格式("format string")
- 数据块包含描述格式的二进制数据。
如果您想了解 DataLogger/Logbook 服务使用的 SBEM 格式,请参阅构建期间创建的 "generated/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"5"
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 团队工作