diff --git a/main/bus/__init__.py b/app/bus/__init__.py similarity index 100% rename from main/bus/__init__.py rename to app/bus/__init__.py diff --git a/main/bus/bus_interface.py b/app/bus/bus_interface.py similarity index 100% rename from main/bus/bus_interface.py rename to app/bus/bus_interface.py diff --git a/main/bus/rs485_manager.py b/app/bus/rs485_manager.py similarity index 84% rename from main/bus/rs485_manager.py rename to app/bus/rs485_manager.py index df3ddc4..f47b4c9 100644 --- a/main/bus/rs485_manager.py +++ b/app/bus/rs485_manager.py @@ -7,37 +7,35 @@ RS485 总线管理器实现 此模块实现了 IBusManager 接口,用于管理 RS485 总线通信。 """ -from .bus_interface import IBusManager -from typing import Dict, Any -from main.logs.logger import log +from ..logs.logger import log # 导入 MicroPython 的 UART 和 Pin 库 from machine import UART, Pin import time # 用于添加延时,确保RS485方向切换 import _thread # 用于线程同步 -import struct # 用于浮点数转换 +import struct # 用于浮点数转换 -class RS485Manager(IBusManager): +class RS485Manager: """ RS485 总线管理器。 负责 RS485 设备的指令发送、响应接收和数据解析。 """ - def __init__(self, bus_config: Dict[int, Dict[str, Any]], default_timeouts: Dict[str, int]): + def __init__(self, bus_config, default_timeouts): """ 构造函数,注入配置。 根据传入的配置初始化 RS485 总线对应的 UART 管理器。 Args: - bus_config (Dict[int, Dict[str, Any]]): 包含所有总线配置的字典。 + bus_config: 包含所有总线配置的字典。 键是总线ID,值是该总线的详细配置。 - default_timeouts (Dict[str, int]): 包含各种默认超时设置的字典。 + default_timeouts: 包含各种默认超时设置的字典。 """ self.bus_config = bus_config self.default_timeouts = default_timeouts # 存储以总线号为key的UART管理器实例、RTS引脚和锁 - self.bus_ports: Dict[int, Dict[str, Any]] = {} + self.bus_ports = {} log("RS485Manager 已使用配置初始化。") log(f"总线配置: {self.bus_config}") @@ -77,7 +75,8 @@ class RS485Manager(IBusManager): else: log(f"总线 {bus_id} 的协议不是 RS485,跳过初始化。") - def _calculate_crc16_modbus(self, data: bytes) -> int: + @staticmethod + def _calculate_crc16_modbus(data): """ 计算 Modbus RTU 的 CRC16 校验码。 """ @@ -85,23 +84,24 @@ class RS485Manager(IBusManager): for byte in data: crc ^= byte for _ in range(8): - if (crc & 0x0001): + if crc & 0x0001: crc >>= 1 crc ^= 0xA001 else: crc >>= 1 return crc - def _parse_modbus_rtu_float_default(self, response_bytes: bytes) -> float | None: + @staticmethod + def _parse_modbus_rtu_float_default(response_bytes): """ 默认解析 Modbus RTU 响应中的 32 位 IEEE 754 单精度浮点数。 假定为大端 (ABCD) 字节序。 """ # 最小预期长度: 从站ID(1) + 功能码(1) + 字节计数(1) + 4字节数据 + CRC(2) = 9字节 - MIN_RESPONSE_LEN = 9 - EXPECTED_DATA_BYTE_COUNT = 4 # 32位浮点数占用4字节 + min_response_len = 9 + expected_data_byte_count = 4 # 32位浮点数占用4字节 - if not response_bytes or len(response_bytes) < MIN_RESPONSE_LEN: + if not response_bytes or len(response_bytes) < min_response_len: log(f"警告: 响应字节过短或为空,无法解析为浮点数。响应: {response_bytes.hex() if response_bytes else 'None'}") return None @@ -110,18 +110,17 @@ class RS485Manager(IBusManager): # response_bytes[:-2] 是用于CRC计算的数据部分 # response_bytes[-2:] 是CRC本身 data_for_crc = response_bytes[:-2] - received_crc = (response_bytes[-1] << 8) | response_bytes[-2] # CRC的低字节在前,高字节在后 + received_crc = (response_bytes[-1] << 8) | response_bytes[-2] # CRC的低字节在前,高字节在后 # 1. CRC 校验 - calculated_crc = self._calculate_crc16_modbus(data_for_crc) + calculated_crc = RS485Manager._calculate_crc16_modbus(data_for_crc) if calculated_crc != received_crc: log(f"错误: CRC校验失败。接收CRC: {received_crc:04X}, 计算CRC: {calculated_crc:04X}. 响应: {response_bytes.hex()}") return None - slave_id = response_bytes[0] function_code = response_bytes[1] byte_count = response_bytes[2] - data_bytes = response_bytes[3:3 + EXPECTED_DATA_BYTE_COUNT] + data_bytes = response_bytes[3:3 + expected_data_byte_count] # 2. 功能码检查 (假设读取保持寄存器0x03或输入寄存器0x04) if function_code not in [0x03, 0x04]: @@ -129,13 +128,13 @@ class RS485Manager(IBusManager): return None # 3. 字节计数检查 - if byte_count != EXPECTED_DATA_BYTE_COUNT: - log(f"警告: 响应字节计数 {byte_count} 不符合预期 (期望{EXPECTED_DATA_BYTE_COUNT})。响应: {response_bytes.hex()}") + if byte_count != expected_data_byte_count: + log(f"警告: 响应字节计数 {byte_count} 不符合预期 (期望{expected_data_byte_count})。响应: {response_bytes.hex()}") return None # 4. 提取的数据字节长度检查 (与字节计数检查有重叠,但更安全) - if len(data_bytes) != EXPECTED_DATA_BYTE_COUNT: - log(f"错误: 提取的数据字节长度不正确。期望{EXPECTED_DATA_BYTE_COUNT}, 实际{len(data_bytes)}. 响应: {response_bytes.hex()}") + if len(data_bytes) != expected_data_byte_count: + log(f"错误: 提取的数据字节长度不正确。期望{expected_data_byte_count}, 实际{len(data_bytes)}. 响应: {response_bytes.hex()}") return None # 5. 转换为浮点数 (大端, ABCD) @@ -147,7 +146,7 @@ class RS485Manager(IBusManager): log(f"错误: 浮点数转换失败: {e}. 数据字节: {data_bytes.hex()}. 响应: {response_bytes.hex()}") return None - def execute_raw_command(self, bus_id: int, command: bytes) -> None: + def execute_raw_command(self, bus_id, command): """ 【契约】执行一个“发后不理”的原始指令。 @@ -176,7 +175,7 @@ class RS485Manager(IBusManager): except Exception as e: log(f"错误: 在总线 {bus_id} 上执行原始命令失败: {e}") - def execute_collect_task(self, task: dict) -> float | None: + def execute_collect_task(self, task): """ 【契约】执行一个完整的采集任务,并直接返回最终的数值。 @@ -188,11 +187,11 @@ class RS485Manager(IBusManager): - 返回最终的float数值,或在任何失败情况下返回None。 Args: - task (dict): 从Protobuf解码出的单个CollectTask消息字典。 + task: 从Protobuf解码出的单个CollectTask消息字典。 期望结构: {"command": {"bus_number": int, "command_bytes": bytes}} Returns: - float | None: 成功解析则返回数值,否则返回None。 + 成功解析则返回数值,否则返回None。 """ # I. 任务参数解析与初步验证 try: @@ -248,7 +247,7 @@ class RS485Manager(IBusManager): # IV. 响应解析与数据提取 (默认 Modbus RTU 浮点数) # TODO: 根据CollectTask的Protobuf定义,此处需要根据parser_type来选择具体的解析逻辑和类型。 # 目前默认使用Modbus RTU大端浮点数解析。 - parsed_value = self._parse_modbus_rtu_float_default(response_bytes) - + parsed_value = RS485Manager._parse_modbus_rtu_float_default(response_bytes) + # V. 返回结果 return parsed_value diff --git a/main/config/config.py b/app/config/config.py similarity index 94% rename from main/config/config.py rename to app/config/config.py index 2874503..3409cbc 100644 --- a/main/config/config.py +++ b/app/config/config.py @@ -22,8 +22,8 @@ LORA_CONFIG = { # LoRa模块连接的GPIO引脚 'pins': { - 'tx': 17, # UART TX - 'rx': 16, # UART RX + 'tx': 5, # UART TX + 'rx': 4, # UART RX }, # LoRa Mesh 模块发送模式(EC: 透传; ED: 完整数据包) @@ -60,9 +60,9 @@ BUS_CONFIG = { # 该总线使用的GPIO引脚 'pins': { - 'tx': 4, # RS485 TX - 'rx': 5, # RS485 RX - 'rts': 2, # RS485 DE/RE 方向控制引脚 + 'tx': 16, # RS485 TX + 'rx': 17, # RS485 RX + 'rts': 15, # RS485 DE/RE 方向控制引脚 } }, diff --git a/main/logs/__init__.py b/app/logs/__init__.py similarity index 100% rename from main/logs/__init__.py rename to app/logs/__init__.py diff --git a/main/logs/logger.py b/app/logs/logger.py similarity index 94% rename from main/logs/logger.py rename to app/logs/logger.py index 8f3122e..5e81fd7 100644 --- a/main/logs/logger.py +++ b/app/logs/logger.py @@ -5,7 +5,7 @@ 一个简单的、可配置的日志记录器模块。 """ -from main.config.config import * +from app.config.config import * def log(message: str): diff --git a/main/lora/__init__.py b/app/lora/__init__.py similarity index 100% rename from main/lora/__init__.py rename to app/lora/__init__.py diff --git a/main/lora/lora_interface.py b/app/lora/lora_interface.py similarity index 100% rename from main/lora/lora_interface.py rename to app/lora/lora_interface.py diff --git a/main/lora/lora_mesh_uart_passthrough_manager.py b/app/lora/lora_mesh_uart_passthrough_manager.py similarity index 98% rename from main/lora/lora_mesh_uart_passthrough_manager.py rename to app/lora/lora_mesh_uart_passthrough_manager.py index 31a58dc..bca4207 100644 --- a/main/lora/lora_mesh_uart_passthrough_manager.py +++ b/app/lora/lora_mesh_uart_passthrough_manager.py @@ -8,13 +8,12 @@ LoRa模块的具体实现 (UART Passthrough for LoRa Mesh) 这个实现针对的是通过UART进行透传的LoRa Mesh模块。 """ -from .lora_interface import ILoraManager -from main.logs.logger import log +from ..logs.logger import log from machine import UART import time -class LoRaMeshUartPassthroughManager(ILoraManager): +class LoRaMeshUartPassthroughManager: """ 通过UART与LoRa Mesh模块通信的处理器实现 (ED模式)。 实现了自动分片与重组逻辑。 diff --git a/main/processor.py b/app/processor.py similarity index 92% rename from main/processor.py rename to app/processor.py index d94b37e..96f3dd1 100644 --- a/main/processor.py +++ b/app/processor.py @@ -8,15 +8,12 @@ - 编排业务流程:解码指令,并将业务任务分发给相应的管理器。 - 完全不关心总线通信和数据解析的技术实现细节。 """ - -# 导入我们定义的“契约”(接口) -from lora.lora_interface import ILoraManager -from bus.bus_interface import IBusManager - +from app.lora.lora_mesh_uart_passthrough_manager import LoRaMeshUartPassthroughManager +from app.bus.rs485_manager import RS485Manager # 导入Protobuf解析代码 -from proto import client_pb +from app.proto import client_pb -from logs.logger import log +from app.logs.logger import log class Processor: @@ -25,7 +22,7 @@ class Processor: 它依赖于抽象的、面向业务的接口。 """ - def __init__(self, lora_handler: ILoraManager, bus_manager: IBusManager): + def __init__(self, lora_handler: LoRaMeshUartPassthroughManager, bus_manager: RS485Manager): """ 构造函数 (依赖注入)。 diff --git a/main/proto/client.proto b/app/proto/client.proto similarity index 100% rename from main/proto/client.proto rename to app/proto/client.proto diff --git a/main/proto/client_pb.py b/app/proto/client_pb.py similarity index 100% rename from main/proto/client_pb.py rename to app/proto/client_pb.py diff --git a/main/uqueue.py b/app/uqueue.py similarity index 100% rename from main/uqueue.py rename to app/uqueue.py diff --git a/main/worker.py b/app/worker.py similarity index 88% rename from main/worker.py rename to app/worker.py index b682593..aed19ee 100644 --- a/main/worker.py +++ b/app/worker.py @@ -10,12 +10,12 @@ - 从队列中取出任务,并交给Processor进行耗时处理。 """ -import uqueue -from processor import Processor -from logs.logger import log +from app.uqueue import Queue +from app.processor import Processor +from app.logs.logger import log -def worker_task(task_queue: uqueue.Queue, processor: Processor): +def worker_task(task_queue: Queue, processor: Processor): """ 工作线程的主函数。 diff --git a/main/main.py b/main.py similarity index 80% rename from main/main.py rename to main.py index 61533b3..42c1805 100644 --- a/main/main.py +++ b/main.py @@ -15,25 +15,23 @@ import time import _thread -from config import config -import uqueue # 导入我们自己创建的本地uqueue模块 +from app.config import config +from app.uqueue import Queue # 导入我们自己创建的本地uqueue模块 # 导入接口和实现 -from lora.lora_interface import ILoraManager -from bus.bus_interface import IBusManager -from lora.lora_mesh_uart_passthrough_manager import LoRaMeshUartPassthroughManager -from bus.rs485_manager import RS485Manager -from processor import Processor +from app.lora.lora_mesh_uart_passthrough_manager import LoRaMeshUartPassthroughManager +from app.bus.rs485_manager import RS485Manager +from app.processor import Processor # 导入工作线程的执行函数 -from worker import worker_task -from logs.logger import log +from app.worker import worker_task +from app.logs.logger import log # --- 模块级变量定义 (带有类型提示) --- -lora_manager: ILoraManager | None = None -bus_manager: IBusManager | None = None +lora_manager: LoRaMeshUartPassthroughManager | None = None +bus_manager: RS485Manager | None = None processor: Processor | None = None -task_queue: uqueue.Queue | None = None +task_queue: Queue | None = None def setup(): @@ -52,7 +50,7 @@ def setup(): # 2. 从配置文件读取队列长度,并创建线程安全的队列 queue_size = config.SYSTEM_PARAMS.get('task_queue_max_size', 10) - task_queue = uqueue.Queue(maxsize=queue_size) + task_queue = Queue(maxsize=queue_size) log(f"任务队列已创建,最大容量: {queue_size}") # 3. 启动工作线程