#!/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('> 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('