112 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			112 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
#!/usr/bin/env python
 | 
						||
# -*- coding: utf-8 -*-
 | 
						||
 | 
						||
"""
 | 
						||
核心业务逻辑处理器 (V3 - 面向业务接口)
 | 
						||
 | 
						||
职责:
 | 
						||
- 编排业务流程:解码指令,并将业务任务分发给相应的管理器。
 | 
						||
- 完全不关心总线通信和数据解析的技术实现细节。
 | 
						||
"""
 | 
						||
 | 
						||
# 导入我们定义的“契约”(接口)
 | 
						||
from lora.lora_interface import ILoraManager
 | 
						||
from bus.bus_interface import IBusManager
 | 
						||
 | 
						||
# 导入Protobuf解析代码
 | 
						||
from proto import client_pb
 | 
						||
 | 
						||
from logs.logger import log
 | 
						||
 | 
						||
 | 
						||
class Processor:
 | 
						||
    """
 | 
						||
    命令处理器类,项目的“大脑”。
 | 
						||
    它依赖于抽象的、面向业务的接口。
 | 
						||
    """
 | 
						||
 | 
						||
    def __init__(self, lora_handler: ILoraManager, bus_manager: IBusManager):
 | 
						||
        """
 | 
						||
        构造函数 (依赖注入)。
 | 
						||
        
 | 
						||
        Args:
 | 
						||
            lora_handler (ILoraManager): 一个实现了LoRa接口的对象。
 | 
						||
            bus_manager (IBusManager): 一个实现了总线接口的对象。
 | 
						||
        """
 | 
						||
        self.lora = lora_handler
 | 
						||
        self.bus = bus_manager
 | 
						||
        log("业务处理器已初始化,准备就绪。")
 | 
						||
 | 
						||
    def handle_packet(self, packet_bytes: bytes):
 | 
						||
        """
 | 
						||
        处理单个LoRa数据包的入口函数。
 | 
						||
        """
 | 
						||
        log(f"收到待处理数据包: {packet_bytes.hex()}")
 | 
						||
 | 
						||
        try:
 | 
						||
            instruction = client_pb.decode_instruction(packet_bytes)
 | 
						||
        except Exception as e:
 | 
						||
            log(f"错误:解码指令失败: {e}")
 | 
						||
            return
 | 
						||
 | 
						||
        # 根据指令类型,分发到不同的业务处理方法
 | 
						||
        if 'raw_485_command' in instruction:
 | 
						||
            self._process_exec_command(instruction['raw_485_command'])
 | 
						||
 | 
						||
        elif 'batch_collect_command' in instruction:
 | 
						||
            self._process_collect_command(instruction['batch_collect_command'])
 | 
						||
 | 
						||
        else:
 | 
						||
            log(f"警告:收到未知或不适用于此设备的指令类型: {instruction}")
 | 
						||
 | 
						||
    def _process_exec_command(self, cmd: dict):
 | 
						||
        """
 | 
						||
        处理“执行命令”业务。
 | 
						||
        """
 | 
						||
        bus_id = cmd['bus_number']
 | 
						||
        command_bytes = cmd['command_bytes']
 | 
						||
        log(f"处理[执行命令]业务:向总线 {bus_id} 下发指令。")
 | 
						||
 | 
						||
        # 直接调用总线接口的业务方法,不关心实现
 | 
						||
        self.bus.execute_raw_command(bus_id, command_bytes)
 | 
						||
        log("执行指令已下发。")
 | 
						||
 | 
						||
    def _process_collect_command(self, cmd: dict):
 | 
						||
        """
 | 
						||
        处理“采集命令”业务。
 | 
						||
        """
 | 
						||
        correlation_id = cmd['correlation_id']
 | 
						||
        tasks = cmd['tasks']
 | 
						||
        log(f"处理[采集命令]业务 (ID: {correlation_id}):共 {len(tasks)} 个任务。")
 | 
						||
 | 
						||
        sensor_values = []
 | 
						||
        for i, task in enumerate(tasks):
 | 
						||
            log(f"  - 执行任务 {i + 1}...")
 | 
						||
 | 
						||
            # 调用总线接口的业务方法,直接获取最终结果
 | 
						||
            # 我们不再关心task的具体内容,也不关心解析过程
 | 
						||
            value = self.bus.execute_collect_task(task)
 | 
						||
 | 
						||
            if value is not None:
 | 
						||
                sensor_values.append(value)
 | 
						||
                log(f"    => 成功,获取值为: {value}")
 | 
						||
            else:
 | 
						||
                # 如果返回None,表示任务失败(超时或解析错误)
 | 
						||
                sensor_values.append(float('nan'))  # 使用NaN表示无效值
 | 
						||
                log("    => 失败,任务未返回有效值。")
 | 
						||
 | 
						||
        # 所有任务执行完毕,构建并发送响应
 | 
						||
        log(f"所有采集任务完成,准备发送响应。采集到的值: {sensor_values}")
 | 
						||
        try:
 | 
						||
            response_payload = {
 | 
						||
                'correlation_id': correlation_id,
 | 
						||
                'values': sensor_values
 | 
						||
            }
 | 
						||
            response_packet = client_pb.encode_instruction('collect_result', response_payload)
 | 
						||
 | 
						||
            # 通过LoRa接口发送出去
 | 
						||
            self.lora.send_packet(response_packet)
 | 
						||
            log("采集结果已通过LoRa发送。")
 | 
						||
        except Exception as e:
 | 
						||
            log(f"错误:编码或发送采集结果失败: {e}")
 |