最近参与的项目需要从智慧用电器上获取电压、电流、温度等数据,我们需要在外网搭建服务器,智慧用电器设置好服务器地址,然后主动与服务器通讯。设备首先要登录服务器,而向服务器发送登录数据包后,需要得到从服务器下发的应答数据包才会上传硬件设备的数据到服务器上。应答数据包包文里有个校验和的字段,刚开始看到这个真是一脸懵逼,不知道这个值是怎么来的。搜了一圈,终于知道计算原理,看了其他人写的函数都不合适,只能自己写一个了。
数据示例:40 40 01 01 15 08 00 00 00 00 01 01 88 11 10 00 00 00 01 08 FF FF 05 00 1B 00 00
00 F1 23 23
倒数第三位为校验和,校验和的位置从第三位到倒数第三位前,将需要所校验和计算的数据取出,
01 01 15 08 00 00 00 00 01 01 88 11 10 00 00 00 01 08 FF FF 05 00 1B 00 00 00
为得到这个校验和的十六进制值,按以下步骤计算
- 先将Bytes转化成10进制数组;数组各元素相加得到总数;如果总数大于0xff,也就是255,则将总数与0xff做与运算;最后需要将数据转成十六进制后取后两位;
看文字可能不太清楚,直接上代码
'''
数据包校验和计算
'''
def checksum(self, data):
checkData = data[2:28]
dataList = [int(x, 16) for x in checkData]
checksum = sum(dataList)
if checksum > 0xff:
checksum = checksum & 0xff
return checksum
这个函数可能还有更简洁的写法,那就是用移位实现数据转换,因为平常比较少用,有空再研究,也希望高手能告诉我怎么写更简洁。
以上大家可得出校验和的值,如果数据包是十六进制的话,还需要做下面一步
str(hex(self.checksum(data)))[2:].zfill(2)
最后将这个值替换校验和字段的值即可。



