from c104 import Client import time import logging # 配置日志 logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) class EnvisionDataReceiver: def __init__(self, server_ip, server_port=2404): """ 初始化远景数据接收器 :param server_ip: 远景系统服务器IP :param server_port: IEC104端口,默认2404 """ self.server_ip = server_ip self.server_port = server_port self.client = None def on_connect(self, connection): """连接成功回调""" logger.info(f"成功连接到远景系统 {connection}") def on_disconnect(self, connection): """断开连接回调""" logger.warning(f"与远景系统断开连接 {connection}") def on_telemetry(self, asdu_address, io_address, value, quality, time): """ 接收遥测数据回调 :param asdu_address: ASDU地址 :param io_address: 信息对象地址 :param value: 值 (归一化值/标度化值/短浮点数) :param quality: 质量描述符 :param time: 时间标签(CP56Time2a格式) """ timestamp = time.to_datetime() if time else None logger.info(f"遥测数据 - ASDU:{asdu_address} IO:{io_address} 值:{value:.2f} 质量:{quality} 时间:{timestamp}") def on_telecommand(self, asdu_address, io_address, state, quality, time): """ 接收遥信数据回调 :param asdu_address: ASDU地址 :param io_address: 信息对象地址 :param state: 状态 (单点/双点) :param quality: 质量描述符 :param time: 时间标签(CP56Time2a格式) """ timestamp = time.to_datetime() if time else None logger.info(f"遥信数据 - ASDU:{asdu_address} IO:{io_address} 状态:{state} 质量:{quality} 时间:{timestamp}") def start(self): """启动客户端连接""" try: # 创建IEC104客户端 self.client = Client() self.client.add_connection(self.server_ip,self.server_port) # 设置回调函数 self.client.on_connect = self.on_connect self.client.on_disconnect = self.on_disconnect self.client.on_telemetry = self.on_telemetry self.client.on_telecommand = self.on_telecommand # 启动连接 self.client.start() logger.info(f"开始连接远景系统 {self.server_ip}:{self.server_port}...") # 保持主线程运行 while True: time.sleep(1) except KeyboardInterrupt: self.stop() except Exception as e: logger.error(f"发生错误: {str(e)}") self.stop() raise e def stop(self): """停止客户端""" if self.client: self.client.stop() logger.info("已停止IEC104客户端") if __name__ == "__main__": # 配置远景系统服务器IP和端口 ENVISION_IP = "192.168.50.242" # 替换为远景系统实际IP ENVISION_PORT = 2404 receiver = EnvisionDataReceiver(ENVISION_IP, ENVISION_PORT) receiver.start()