2 回答

TA贡献1784条经验 获得超9个赞
发帖者似乎正在尝试从 BMV700 电池监视器读取数据。阅读此处的论文,我们看到它使用文本协议通过串行接口进行通信:
2 文本协议
当没有 VE.Direct 查询发送到设备时,充电器会定期将人类可读 (TEXT) 数据发送到串行端口。有关内容和信息可用性的详细说明,请参阅“VE.Direct Protocol”文档
摘自 HEX 协议 (BMV-7xx-HEX-Protocol-public.pdf)
查看 TEXT 协议的规范 (VE.Direct-Protocol-3.28.pdf),我们发现:
消息格式
该设备以 1 秒的间隔传输数据块。每个字段都使用以下格式发送:
<Newline><Field-Label><Tab><Field-Value>
标识符定义如下:
+---------------+--------------------------------------------------------------------------------------+
| Identifier | Meaning |
+===============+======================================================================================+
| <Newline> | A carriage return followed by a line feed (0x0D, 0x0A). |
+---------------+--------------------------------------------------------------------------------------+
| <Field-Label> | An arbitrary length label that identifies the field. |
| | Where applicable, this will be the same as the label that is used on the LCD. |
+---------------+--------------------------------------------------------------------------------------+
| <Tab> | A horizontal tab (0x09). |
+---------------+--------------------------------------------------------------------------------------+
| <Field-Value> | The ASCII formatted value of this field. |
| | The number of characters transmitted depends on the magnitude and sign of the value. |
+---------------+--------------------------------------------------------------------------------------+
这对应于您正在打印的数据,但有一个例外:该行以 开头,\r\b但不以它们结尾。
然后,该文件提供了有关校验和的详细信息:
数据的完整性
统计数据分组为块,并附加了校验和。块中的最后一个字段将始终是“校验和”。该值是一个字节,不一定是可打印的 ASCII 字符。如果没有传输错误,块中所有字节的模 256 和将等于 0。发送包含不同字段的多个块。
因此,在您作为输出发布的摘录中,您有两个完整的块和一个不完整的块,因为最后一个块缺少Checksum.
block = (b'\r\nH2\t0\r\n'
b'H4\t0\r\n'
b'H6\t-9001\r\n'
b'H8\t28403\r\n'
b'H10\t0\r\n'
b'H12\t0\r\n'
b'H18\t87\r\n'
b'PID\t0x203\r\n'
b'I\t0\r\n'
b'CE\t0\r\n'
b'TTG\t-1\r\n'
b'Relay\tOFF\r\n'
b'BMV\t700\r\n'
b'Checksum\t\xd6')
请注意,我\r\n在开头添加了,并从块的末尾删除了它们,这样最后一个字节就是块的校验和。
现在,我们可以计算块的校验和:
>>> sum(block) % 256
213
这应该是零。因此,可能存在一些传输问题,或者他们计算校验和的方式可能与他们在文档中所说的不同。
新数据后编辑。
这是我用来检查您发布的所有块的代码:
current_block = []
# it's unfortunate that lines start with `\r\n` rather than end with it
# we will read the first empty line separatey, and then include these
# 2 characters in the last line that is read
message = bmvdata.readline()
while True:
# Note that we cannot decode yet, since the Checksum value may not be a valid utf8 character
message = bmvdata.readline()
# we save the message in the current block before any preprocessing
current_block.append(message)
#splitting on tabs (as bytes !!)
message_parts = message.split(b'\t')
if len(message_parts) > 1:
key = message_parts[0].decode('utf8') # here it is safe to decode the key
value = message_parts[1].rstrip() #stripping \r\n after the value
if key == 'Checksum':
block_chars = b''.join(current_block)
checksum = sum(block_chars) % 256
print('Retrieved checksum', value[-1])
print('Calculated checksum', checksum)
print('----')
# reset the block
current_block = []
奇怪的是,对于第一次运行,您总是得到等于检索到的计算值 + 1,但在第二次运行中却没有。因此,可能存在一些传输问题。

TA贡献1848条经验 获得超10个赞
下面的代码比较了两个文件,在这种情况下,正如提问者提到的校验和:
bmvdata = batteryConnect(self.port,self.baudrate)
bmvdata.flushInput()
print(bmvdata.readline())
它是在hashlib的帮助下完成的
import hashlib
#File 1 = checksum
hasher1 = hashlib.md5()
#afile1 = open('checksum', 'rb')
buf1 = bmvdata.read()
#buf1 = afile1.read()
a = hasher1.update(buf1)
md5_a=(str(hasher1.hexdigest()))
#File 2
hasher2 = hashlib.md5()
afile2 = open('incoming-byte', 'rb')
buf2 = afile2.read()
b = hasher2.update(buf2)
md5_b=(str(hasher2.hexdigest()))
#Compare md5
if(md5_a==md5_b):
print("Yes")
else:
print("No")
添加回答
举报