Newer
Older
go-algo-server / handle_tcp_command.py
zhangyingjie on 24 Mar 4 KB 增加甲烷浓度监测上报
import asyncio
import base64
import json
import re
import time
import cv2
from global_logger import logger, process_log_data


class HandelTCPCommand:
    def __init__(self, camera_processors, http_client):
        self.camera_processors = camera_processors
        self.http_client = http_client

    async def capture_and_send_current_frame(self, camera_processor, preset, gas_data, longitude, latitude):
        """捕获当前帧并通过HTTP发送到后台"""

        cam_id = camera_processor.cam_id
        logger.info(f"摄像头 {cam_id} 准备捕获并发送当前帧")

        # 使用get_last_frame方法获取最后一帧,不直接访问内部属性
        frame = camera_processor.get_last_frame()
        if frame is None:
            logger.warning(f"摄像头 {cam_id} 没有可用的帧")
            return False

        try:
            skip_img = int(preset) == 5 and float(gas_data) <= 0
            # 将图像编码为JPEG
            success, jpg_data = cv2.imencode('.jpg', frame) if not skip_img else (True, None)
            if not success:
                logger.error(f"摄像头 {cam_id} 编码图像失败")
                return False

            def get_cap_content(preset, gas_data):
                map = {
                    "1": ('10006', '第三方施工监测', 1),
                    "2": ('10007', '闸井监测', 0),
                    "3": ('10008', '引入口监测', 0),
                    "4": ('10009', '调压箱监测 ', 0),
                    "5": ('10011', '燃气泄漏', 0 if float(gas_data) <= 0 else 1),
                }
                return map.get(str(preset), ('', '', 0))

            # 构建请求数据
            report_type, content, status = get_cap_content(preset, gas_data)

            if int(preset) == 5:
                status = 0 if float(gas_data) <= 0 else 1

            request_data = {
                "routeNumber": preset,
                "picture": base64.b64encode(jpg_data.tobytes()).decode('utf-8') if (jpg_data is not None and jpg_data.size > 0) else '',
                "reportType": report_type,
                "reportContent": content,
                "isAlarm": status,
                "reportValue": gas_data,
                "gpsPoints": f'{longitude},{latitude}'
            }

            logger.debug(process_log_data(request_data))
            # 发送HTTP请求
            await self.http_client.send([request_data])
            logger.info(f"摄像头 {cam_id} 已发送当前帧到后台")
            return True
        except Exception as e:
            logger.exception(f"发送当前帧时发生错误: {e}")
            return False

    async def handle_capture_command(self, message):
        """处理TCP服务器发来的命令"""
        try:
            logger.info(f"处理TCP命令: {message}")

            pattern = r"^(\d+),([^,]+),([^,]+),([^,]+)$"

            # 检查是否是捕获图像的命令
            match = re.match(pattern, message.strip())
            if match:
                preset, gas_data, longitude, latitude = match.groups()

                logger.debug(f"preset = {preset}, gas_data = {gas_data}, longitude = {longitude}, latitude = {latitude}")

                # 对所有摄像头执行
                for cam_id, processor in self.camera_processors.items():
                    await self.capture_and_send_current_frame(processor, preset, gas_data, longitude, latitude)

                logger.info("图像捕获和发送完成")

                # 发送处理完成的响应
                response = {
                    "status": "success",
                    "timestamp": time.time(),
                    "message": "图像已成功捕获并发送"
                }
                return response
        except json.JSONDecodeError:
            logger.error(f"无法解析JSON命令: {message}")
        except Exception as e:
            logger.exception(f"处理TCP命令时出错: {e}")

        # 发送错误响应
        return {
            "status": "error",
            "timestamp": time.time(),
            "message": "处理命令时出错"
        }