From 60a05121cb04752976a0d72b0bbbc2fef98f20c5 Mon Sep 17 00:00:00 2001 From: haotian <2421912570@qq.com> Date: Tue, 3 Jun 2025 14:23:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0,=20=E6=B7=BB=E5=8A=A0robot?= =?UTF-8?q?=E8=A1=A8,=20websocket=E4=B8=AD=E5=A2=9E=E5=8A=A0=E5=AF=B9?= =?UTF-8?q?=E6=9C=BA=E5=99=A8=E4=BA=BA=E7=8A=B6=E6=80=81=E7=9A=84=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/config.py | 6 ++- app/models/models.py | 13 +++++- app/services/event_sync_service.py | 75 +++++++++++++++++++++++++++++- app/services/websocket_service.py | 16 ++++++- app/util/kangda.py | 2 + app/util/status.py | 8 +++- run_sync.py | 4 +- 7 files changed, 115 insertions(+), 9 deletions(-) diff --git a/app/core/config.py b/app/core/config.py index a66c714..c45f1ce 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -2,10 +2,12 @@ from pydantic_settings import BaseSettings class Settings(BaseSettings): # 数据库配置 - DB_HOST: str = "14.103.162.172" + # DB_HOST: str = "14.103.162.172" + DB_HOST: str = "10.0.0.17" DB_PORT: int = 3306 DB_USER: str = "root" - DB_PASSWORD: str = "dnxxkj" + # DB_PASSWORD: str = "dnxxkj" + DB_PASSWORD: str = "root" DB_NAME: str = "kangda" # DB_NAME: str = "kangda_test" # 测试数据库 diff --git a/app/models/models.py b/app/models/models.py index c454fa6..74584bf 100644 --- a/app/models/models.py +++ b/app/models/models.py @@ -90,7 +90,7 @@ class Temperature(Base): tempId = Column(BigInteger, primary_key=True, autoincrement=True, comment='温度记录ID') eventId = Column(String(50), ForeignKey('event.eventId', ondelete="CASCADE"), nullable=False, comment='关联事件ID') imageId = Column(BigInteger, ForeignKey('image.imageId', ondelete="CASCADE"), nullable=False, comment='关联图片ID') - temperature = Column(String(20), nullable=False, comment='温度值') + temperature = Column(String(100), nullable=False, comment='温度值') status = Column(String(5), comment='温度是否正常') confidence = Column(String(40), nullable=False, comment='识别置信度') createTime = Column(DateTime, default=datetime.now, nullable=False, comment='创建时间') @@ -142,6 +142,17 @@ class Message(Base): Index('idx_message_update_time', 'updateTime'), ) + +class Robot(Base): + __tablename__ = "robot" + + robotId = Column(String(100), primary_key=True, comment='机器人ID') + number = Column(String(50), comment='机器人名称/名称') + groupingId = Column(String(100), comment='分组ID') + onlineStatus = Column(String(5), comment='在线状态') + status = Column(String(5), comment='机器人状态') + createTime = Column(DateTime, default=datetime.now, nullable=False, comment='创建时间') + updateTime = Column(DateTime, default=datetime.now, nullable=False, comment='更新时间') diff --git a/app/services/event_sync_service.py b/app/services/event_sync_service.py index 236a663..41bed27 100644 --- a/app/services/event_sync_service.py +++ b/app/services/event_sync_service.py @@ -1,10 +1,12 @@ import asyncio from datetime import datetime +from telnetlib import AYT +from tkinter import W from typing import List, Dict, Any from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.core.database import async_session -from app.models.models import Event, Image, Temperature, Message +from app.models.models import Event, Image, Temperature, Message, Robot from app.util.kangda import Kangda from app.util.baiduOcr import BadiduOcr from app.util.status import EventType @@ -14,6 +16,10 @@ class EventSyncService: def __init__(self): self.kangda = Kangda() self.ocr = BadiduOcr() + self.robot_dict = None + + + async def sync_events(self): """同步事件数据""" @@ -39,6 +45,71 @@ class EventSyncService: print("事件同步完成") + # 同步机器人状态 + async def sync_robot_status(self, message: dict): + """同步机器人状态""" + print(f"开始同步机器人状态") + + # 机器人列表为空时请求数据库 + if self.robot_dict is None: + await self._get_robot_dict() + + # 机器人信息在保存的机器人字典中,// 避免频繁查询/更新数据库. + if message["robotId"] in self.robot_dict: + # 修改在线状态 + if self.robot_dict[message["robotId"]].onlineStatus != message["onlineStatus"]: + await self._update_robot_online_status(self.robot_dict[message["robotId"]]) + self.robot_dict[message["robotId"]].onlineStatus = message["onlineStatus"] + # 新增机器人消息 + else: + await self._add_robot(message) + self.robot_dict[message["robotId"]] = message + + + async def _add_robot(self, message): + """新增机器人""" + try: + async with async_session() as session: + robot = Robot( + robotId=message["robotId"], + onlineStatus=message["onlineStatus"], + number=message["number"], + groupingId=message["groupingId"], + status="0" + ) + session.add(robot) + await session.commit() + except Exception as e: + print(f"添加机器人失败: {e}") + + # 更新机器人在线状态 + async def _update_robot_online_status(self, robot): + """更新机器人在线状态""" + try: + async with async_session() as session: + update = ( + update(Robot).where(Robot.robotId == robot.robotId).values( + onlineStatus = robot.onlineStatus + ) + ) + await session.execute(update) + await session.commit() + except Exception as e: + print(f"更新机器人在线状态失败: {e}") + + + async def _get_robot_dict(self): + """获取机器人状态""" + async with async_session() as session: + query = select(Robot) + result = await session.execute(query) + robot_list = result.scalars().all() + # 将机器人列表转换为字典 + self.robot_dict = dict() + for robot in robot_list: + self.robot_dict[robot.robotId] = robot + # return robot_list + # 同步单个事件 async def sync_event(self, eventId: str): """同步单个事件""" @@ -156,7 +227,7 @@ class EventSyncService: if not existing_image: # 下载图片 - local_path = self.kangda._download_image(image_url, save_image=False) + local_path = self.kangda._download_image(image_url, save_image=True) # 创建图片记录 image = Image( diff --git a/app/services/websocket_service.py b/app/services/websocket_service.py index 038429d..017d2a6 100644 --- a/app/services/websocket_service.py +++ b/app/services/websocket_service.py @@ -79,6 +79,11 @@ class WebSocketClient: print("触发事件同步...") await self.event_sync_service.sync_event(message_dict.get("eventId")) + # 机器人状态消息 + elif self._process_robot_status(message_dict): + print("处理机器人状态消息...") + + await self.event_sync_service.sync_robot_status(message_dict) # await run_sync_event(t) @@ -86,6 +91,15 @@ class WebSocketClient: print("收到非JSON格式消息") except Exception as e: print(f"处理消息时出错: {str(e)}") + + def _process_robot_status(self, message: dict): + """处理机器人状态消息""" + try: + # 以onlineStatus判断是否是机器人消息 + return message.get("onlineStatus", None) is not None + except Exception as e: + print(f"处理机器人状态消息时出错: {str(e)}") + return False def _should_trigger_sync(self, message: dict) -> bool: """判断是否需要触发事件同步""" @@ -113,7 +127,7 @@ class WebSocketClient: try: # 接收消息 message = await websocket.recv() - print(f"收到消息: {message[:100]}...") # 只打印前100个字符 + print(f"{datetime.now()}收到消息: {message[:100]}...") # 只打印前100个字符 # 处理消息 await self.process_message(message) diff --git a/app/util/kangda.py b/app/util/kangda.py index a27ed4b..7e0c484 100644 --- a/app/util/kangda.py +++ b/app/util/kangda.py @@ -29,6 +29,8 @@ class Kangda: return event_list + + # 获取事件列表详情 def get_event_list_detail(self, results): diff --git a/app/util/status.py b/app/util/status.py index c7e5fc2..8d419d4 100644 --- a/app/util/status.py +++ b/app/util/status.py @@ -11,7 +11,13 @@ class TemperatureStatus(Enum): @unique class EventType(Enum): - HOT = 0 # 温度异常报警 + HOT = 0 # 读表温度异常报警 + HightTemperature = 1 # 高温报警 + SMOKE = 2 # 吸烟报警 + LONGSTAY = 3 # 长时间滞留报警 + AIRQUALITY = 4 # 空气质量报警 + STOPEMERGENCY = 5 # 急停按下 + VOICENOTCONNECT = 6 #语音未接通 \ No newline at end of file diff --git a/run_sync.py b/run_sync.py index f2be188..a956e27 100644 --- a/run_sync.py +++ b/run_sync.py @@ -7,5 +7,5 @@ from app.services.event_sync_service import run_sync, run_sync_event if __name__ == "__main__": print("启动事件同步服务...") - # asyncio.run(run_sync()) - asyncio.run(run_sync_event("55ec55e886474b4f93390e71ea46c64d")) \ No newline at end of file + asyncio.run(run_sync()) + # asyncio.run(run_sync_event("6c1cc5c6a4c74af0ba8932f5db7023f4")) \ No newline at end of file