简易版代码
This commit is contained in:
306
client_pb.py
Normal file
306
client_pb.py
Normal file
@@ -0,0 +1,306 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
根据client.proto生成的解析代码
|
||||
适用于ESP32 MicroPython环境
|
||||
"""
|
||||
|
||||
import struct
|
||||
|
||||
# MethodType枚举
|
||||
METHOD_TYPE_SWITCH = 0
|
||||
METHOD_TYPE_COLLECT = 1
|
||||
|
||||
def encode_varint(value):
|
||||
"""编码varint值"""
|
||||
buf = bytearray()
|
||||
while value >= 0x80:
|
||||
buf.append((value & 0x7F) | 0x80)
|
||||
value >>= 7
|
||||
buf.append(value & 0x7F)
|
||||
return buf
|
||||
|
||||
def decode_varint(buf, pos=0):
|
||||
"""解码varint值"""
|
||||
result = 0
|
||||
shift = 0
|
||||
while pos < len(buf):
|
||||
byte = buf[pos]
|
||||
pos += 1
|
||||
result |= (byte & 0x7F) << shift
|
||||
if not (byte & 0x80):
|
||||
break
|
||||
shift += 7
|
||||
return result, pos
|
||||
|
||||
def encode_string(value):
|
||||
"""编码字符串"""
|
||||
value_bytes = value.encode('utf-8')
|
||||
length = encode_varint(len(value_bytes))
|
||||
return length + value_bytes
|
||||
|
||||
def decode_string(buf, pos=0):
|
||||
"""解码字符串"""
|
||||
length, pos = decode_varint(buf, pos)
|
||||
value = buf[pos:pos+length].decode('utf-8')
|
||||
pos += length
|
||||
return value, pos
|
||||
|
||||
def encode_instruction(method, data):
|
||||
"""
|
||||
编码Instruction消息
|
||||
|
||||
Args:
|
||||
method: 方法类型 (int)
|
||||
data: 数据 (bytes)
|
||||
|
||||
Returns:
|
||||
bytearray: 编码后的数据
|
||||
"""
|
||||
result = bytearray()
|
||||
|
||||
# 编码method字段 (field_number=1, wire_type=0)
|
||||
result.extend(encode_varint((1 << 3) | 0)) # tag
|
||||
result.extend(encode_varint(method)) # value
|
||||
|
||||
# 编码data字段 (field_number=2, wire_type=2)
|
||||
result.extend(encode_varint((2 << 3) | 2)) # tag
|
||||
result.extend(encode_varint(len(data))) # length
|
||||
result.extend(data) # value
|
||||
|
||||
return result
|
||||
|
||||
def decode_instruction(buf):
|
||||
"""
|
||||
解码Instruction消息
|
||||
|
||||
Args:
|
||||
buf: 编码后的数据 (bytes)
|
||||
|
||||
Returns:
|
||||
dict: 解码后的消息
|
||||
"""
|
||||
result = {}
|
||||
pos = 0
|
||||
|
||||
while pos < len(buf):
|
||||
# 读取标签
|
||||
tag, pos = decode_varint(buf, pos)
|
||||
field_number = tag >> 3
|
||||
wire_type = tag & 0x07
|
||||
|
||||
if field_number == 1: # method字段
|
||||
if wire_type == 0: # varint类型
|
||||
value, pos = decode_varint(buf, pos)
|
||||
result['method'] = value
|
||||
elif field_number == 2: # data字段
|
||||
if wire_type == 2: # 长度分隔类型
|
||||
length, pos = decode_varint(buf, pos)
|
||||
value = buf[pos:pos+length]
|
||||
pos += length
|
||||
result['data'] = value
|
||||
else:
|
||||
# 跳过未知字段
|
||||
if wire_type == 0: # varint
|
||||
_, pos = decode_varint(buf, pos)
|
||||
elif wire_type == 2: # 长度分隔
|
||||
length, pos = decode_varint(buf, pos)
|
||||
pos += length
|
||||
else:
|
||||
pos += 1
|
||||
|
||||
return result
|
||||
|
||||
def encode_switch(device_action, bus_number, bus_address, relay_channel):
|
||||
"""
|
||||
编码Switch消息
|
||||
|
||||
Args:
|
||||
device_action: 设备动作指令 (str)
|
||||
bus_number: 总线号 (int)
|
||||
bus_address: 总线地址 (int)
|
||||
relay_channel: 继电器通道号 (int)
|
||||
|
||||
Returns:
|
||||
bytearray: 编码后的数据
|
||||
"""
|
||||
result = bytearray()
|
||||
|
||||
# 编码device_action字段 (field_number=1, wire_type=2)
|
||||
result.extend(encode_varint((1 << 3) | 2)) # tag
|
||||
action_bytes = encode_string(device_action) # value (length + string)
|
||||
result.extend(action_bytes)
|
||||
|
||||
# 编码bus_number字段 (field_number=2, wire_type=0)
|
||||
result.extend(encode_varint((2 << 3) | 0)) # tag
|
||||
result.extend(encode_varint(bus_number)) # value
|
||||
|
||||
# 编码bus_address字段 (field_number=3, wire_type=0)
|
||||
result.extend(encode_varint((3 << 3) | 0)) # tag
|
||||
result.extend(encode_varint(bus_address)) # value
|
||||
|
||||
# 编码relay_channel字段 (field_number=4, wire_type=0)
|
||||
result.extend(encode_varint((4 << 3) | 0)) # tag
|
||||
result.extend(encode_varint(relay_channel)) # value
|
||||
|
||||
return result
|
||||
|
||||
def decode_switch(buf):
|
||||
"""
|
||||
解码Switch消息
|
||||
|
||||
Args:
|
||||
buf: 编码后的数据 (bytes)
|
||||
|
||||
Returns:
|
||||
dict: 解码后的消息
|
||||
"""
|
||||
result = {}
|
||||
pos = 0
|
||||
|
||||
while pos < len(buf):
|
||||
# 读取标签
|
||||
tag, pos = decode_varint(buf, pos)
|
||||
field_number = tag >> 3
|
||||
wire_type = tag & 0x07
|
||||
|
||||
if field_number == 1: # device_action字段
|
||||
if wire_type == 2: # 字符串类型
|
||||
value, pos = decode_string(buf, pos)
|
||||
result['device_action'] = value
|
||||
elif field_number == 2: # bus_number字段
|
||||
if wire_type == 0: # varint类型
|
||||
value, pos = decode_varint(buf, pos)
|
||||
result['bus_number'] = value
|
||||
elif field_number == 3: # bus_address字段
|
||||
if wire_type == 0: # varint类型
|
||||
value, pos = decode_varint(buf, pos)
|
||||
result['bus_address'] = value
|
||||
elif field_number == 4: # relay_channel字段
|
||||
if wire_type == 0: # varint类型
|
||||
value, pos = decode_varint(buf, pos)
|
||||
result['relay_channel'] = value
|
||||
else:
|
||||
# 跳过未知字段
|
||||
if wire_type == 0: # varint
|
||||
_, pos = decode_varint(buf, pos)
|
||||
elif wire_type == 2: # 长度分隔
|
||||
length, pos = decode_varint(buf, pos)
|
||||
pos += length
|
||||
else:
|
||||
pos += 1
|
||||
|
||||
return result
|
||||
|
||||
def encode_collect(bus_number, bus_address, value):
|
||||
"""
|
||||
编码Collect消息
|
||||
|
||||
Args:
|
||||
bus_number: 总线号 (int)
|
||||
bus_address: 总线地址 (int)
|
||||
value: 采集值 (float)
|
||||
|
||||
Returns:
|
||||
bytearray: 编码后的数据
|
||||
"""
|
||||
result = bytearray()
|
||||
|
||||
# 编码bus_number字段 (field_number=1, wire_type=0)
|
||||
result.extend(encode_varint((1 << 3) | 0)) # tag
|
||||
result.extend(encode_varint(bus_number)) # value
|
||||
|
||||
# 编码bus_address字段 (field_number=2, wire_type=0)
|
||||
result.extend(encode_varint((2 << 3) | 0)) # tag
|
||||
result.extend(encode_varint(bus_address)) # value
|
||||
|
||||
# 编码value字段 (field_number=3, wire_type=5)
|
||||
result.extend(encode_varint((3 << 3) | 5)) # tag
|
||||
# 将float转换为little-endian的4字节
|
||||
result.extend(struct.pack('<f', value)) # value
|
||||
|
||||
return result
|
||||
|
||||
def decode_collect(buf):
|
||||
"""
|
||||
解码Collect消息
|
||||
|
||||
Args:
|
||||
buf: 编码后的数据 (bytes)
|
||||
|
||||
Returns:
|
||||
dict: 解码后的消息
|
||||
"""
|
||||
result = {}
|
||||
pos = 0
|
||||
|
||||
while pos < len(buf):
|
||||
# 读取标签
|
||||
tag, pos = decode_varint(buf, pos)
|
||||
field_number = tag >> 3
|
||||
wire_type = tag & 0x07
|
||||
|
||||
if field_number == 1: # bus_number字段
|
||||
if wire_type == 0: # varint类型
|
||||
value, pos = decode_varint(buf, pos)
|
||||
result['bus_number'] = value
|
||||
elif field_number == 2: # bus_address字段
|
||||
if wire_type == 0: # varint类型
|
||||
value, pos = decode_varint(buf, pos)
|
||||
result['bus_address'] = value
|
||||
elif field_number == 3: # value字段
|
||||
if wire_type == 5: # 32位浮点类型
|
||||
# 从little-endian的4字节解析float
|
||||
value = struct.unpack('<f', buf[pos:pos+4])[0]
|
||||
pos += 4
|
||||
result['value'] = value
|
||||
else:
|
||||
# 跳过未知字段
|
||||
if wire_type == 0: # varint
|
||||
_, pos = decode_varint(buf, pos)
|
||||
elif wire_type == 5: # 32位固定长度
|
||||
pos += 4
|
||||
elif wire_type == 2: # 长度分隔
|
||||
length, pos = decode_varint(buf, pos)
|
||||
pos += length
|
||||
else:
|
||||
pos += 1
|
||||
|
||||
return result
|
||||
|
||||
# 使用示例
|
||||
if __name__ == "__main__":
|
||||
# 创建一个Switch消息
|
||||
switch_data = encode_switch("ON", 1, 10, 2)
|
||||
print(f"编码后的Switch消息: {switch_data.hex()}")
|
||||
|
||||
# 创建一个Instruction消息,包含Switch数据
|
||||
instruction_data = encode_instruction(METHOD_TYPE_SWITCH, switch_data)
|
||||
print(f"编码后的Instruction消息: {instruction_data.hex()}")
|
||||
|
||||
# 解码Instruction消息
|
||||
decoded_instruction = decode_instruction(instruction_data)
|
||||
print(f"解码后的Instruction消息: {decoded_instruction}")
|
||||
|
||||
# 解码Switch消息
|
||||
if 'data' in decoded_instruction:
|
||||
decoded_switch = decode_switch(decoded_instruction['data'])
|
||||
print(f"解码后的Switch消息: {decoded_switch}")
|
||||
|
||||
# 创建一个Collect消息
|
||||
collect_data = encode_collect(1, 20, 25.6)
|
||||
print(f"编码后的Collect消息: {collect_data.hex()}")
|
||||
|
||||
# 创建一个Instruction消息,包含Collect数据
|
||||
instruction_data2 = encode_instruction(METHOD_TYPE_COLLECT, collect_data)
|
||||
print(f"编码后的Instruction消息(Collect): {instruction_data2.hex()}")
|
||||
|
||||
# 解码Instruction消息
|
||||
decoded_instruction2 = decode_instruction(instruction_data2)
|
||||
print(f"解码后的Instruction消息: {decoded_instruction2}")
|
||||
|
||||
# 解码Collect消息
|
||||
if 'data' in decoded_instruction2:
|
||||
decoded_collect = decode_collect(decoded_instruction2['data'])
|
||||
print(f"解码后的Collect消息: {decoded_collect}")
|
||||
Reference in New Issue
Block a user