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")
添加回答
舉報