import time from concurrent.futures import ThreadPoolExecutor import requests from enum import Enum from typing import Optional, Dict, Any class DeviceStatus(Enum): """设备状态枚举""" NORMAL = 0 ABNORMAL = 1 class ErrorCode(Enum): """错误代码枚举""" EMERGENCY_STOP = 1 EQUIPMENT_ERROR = 2 class AndonEndpoint(Enum): """API端点枚举""" HEARTBEAT = "/heartbeat" JOB_START = "/job_start" JOB_END = "/job_end" JOB_ERROR = "/job_error" CALL = "/call" class SimpleAndonSender: """简化版 Andon 发送器""" def __init__(self, server_ip: str = "192.168.2.1", port: int = 5100, timeout: int = 5): self.base_url = f"http://{server_ip}:{port}" self.timeout = timeout # 状态记录 self.last_start: Optional[int] = None self.last_end: Optional[int] = None self.error_status = True self.stop_status = True self.call_status = True # 消息队列 self.thread_pool = ThreadPoolExecutor(max_workers=5, thread_name_prefix="AndonSender") # 会话对象,支持连接池 self.session = requests.Session() def send_mes_thread(self, m_values, device_id=1): self.thread_pool.submit(self.send_all_status, device_id, m_values) def send_all_status(self, device_id: int, m_values: list) -> None: """发送所有状态""" print("发送心跳") self._post(AndonEndpoint.HEARTBEAT, {"id": device_id, "status": 1}) # 解析状态值 status = self._parse_status_values(m_values) print(status) # 处理作业状态 self._handle_job_status(device_id, status) # 处理信号状态(按优先级) self._handle_signal_status(device_id, status) def _parse_status_values(self, m_values: list) -> Dict[str, int]: """解析状态值""" return { 'start': int(m_values[1]), # 开始工作状态位 'end': int(m_values[12]), # 结束工作状态位 'stop': int(m_values[11]), # 急停状态位 'call': int(m_values[10]), # 呼叫状态位 'error': int(m_values[2]) # 异常状态位 } def _handle_job_status(self, device_id: int, status: Dict[str, int]) -> None: """处理作业状态""" # 开始工作检测 if status['start'] == 1 and self.last_start != 1: print("发送作业开始") self._post(AndonEndpoint.JOB_START, {"id": device_id, "elapsed_time": 0}) self.last_start = 1 # 结束工作检测 if status['end'] == 1: print("发送作业结束") self._post(AndonEndpoint.JOB_END, {"id": device_id}) self.last_start = 0 self.last_end = 0 def _handle_signal_status(self, device_id: int, status: Dict[str, int]) -> None: """处理信号状态(按优先级:呼叫 > 异常 > 急停)""" call_handled = self._handle_call_status(device_id, status['call']) if not call_handled: error_handled = self._handle_error_status(device_id, status['error']) if not error_handled: self._handle_stop_status(device_id, status['stop']) def _handle_call_status(self, device_id: int, call_value: int) -> bool: """处理呼叫状态""" if call_value == 1: print("发送呼叫") self._post(AndonEndpoint.CALL, {"id": device_id, "call_status": 1}) self.call_status = True return True elif call_value == 0 and self.call_status: print("发送呼叫复位") self._post(AndonEndpoint.CALL, {"id": device_id, "call_status": 0}) self.call_status = False return False def _handle_error_status(self, device_id: int, error_value: int) -> bool: """处理异常状态""" if error_value == 1: print("发送异常") self._post(AndonEndpoint.JOB_ERROR, { "id": device_id, "error_type": 1, "error_code": ErrorCode.EQUIPMENT_ERROR.value }) self.error_status = True return True elif error_value == 0 and self.error_status: print("发送异常复位") self._post(AndonEndpoint.JOB_ERROR, { "id": device_id, "error_type": 0, "error_code": ErrorCode.EQUIPMENT_ERROR.value }) self.error_status = False return False def _handle_stop_status(self, device_id: int, stop_value: int) -> bool: """处理急停状态""" if stop_value == 1: print("紧急停止") self._post(AndonEndpoint.JOB_ERROR, { "id": device_id, "error_type": 1, "error_code": ErrorCode.EMERGENCY_STOP.value }) self.stop_status = True return True elif stop_value == 0 and self.stop_status: print("紧急停止复位") self._post(AndonEndpoint.JOB_ERROR, { "id": device_id, "error_type": 0, "error_code": ErrorCode.EMERGENCY_STOP.value }) self.stop_status = False return False def _post(self, endpoint: AndonEndpoint, data: Dict[str, Any]) -> Optional[Dict[str, Any]]: """发送POST请求""" url = f"{self.base_url}{endpoint.value}" try: response = self.session.post(url, json=data, timeout=self.timeout) response.raise_for_status() # 如果状态码不是200,抛出异常 return response.json() except Exception as e: print(f"发送失败到 {url}: {e}") return None if __name__ == '__main__': """主函数 - 监听键盘输入并调用自定义方法""" andon_sender = SimpleAndonSender(server_ip='127.0.0.1', port=5100) # device_id = 1 # 默认设备ID """ 0000000000000 # stop 0000000000010 # error 0010000000000 # 0000000000001 0100000000000 """ # while True: # cmd = input("> ").strip() # print(cmd) # andon_sender.send_mes_thread(cmd) # time.sleep(1)