#!/usr/bin/env python # -*- coding: utf-8 -*- ''' # @Time : 2025/6/19 11:20 # @Author : reenrr # @File : EMV-test1.py # 功能描述 :通过网络控制继电器模块,实现对冲压机素面操作按钮、烫金操作按钮和紧急停止按钮的远程控制 ''' import socket import binascii import time # 网络继电器的 IP 和端口 # 冲压机20 HOST = '192.168.58.20' PORT = 50000 # 素面操作按钮(冲压机)或高压启动按钮(高周波) RESIN_MOLDING_BUTTON ='resin_molding_button' # 烫金操作按钮 FINSHING_AGENT_BUTTON = 'finishing_agent_button' # 紧急停止按钮 STOP_BUTTON = 'stop_button' ''' 控件控制报文,存储各按钮的开关命令 ''' valve_commands = { RESIN_MOLDING_BUTTON: { 'open': '00000000000601050000FF00', 'close': '000000000006010500000000', }, FINSHING_AGENT_BUTTON: { 'open': '00000000000601050001FF00', 'close': '000000000006010500010000', }, STOP_BUTTON: { 'open': '00000000000601050002FF00', 'close': '000000000006010500020000', } } ''' 读取状态命令,获取设备当前状态的指令 ''' read_status_command = { 'button':'000000000006010100000008', } # 控件对应 DO 位(从低到高) button_bit_map = { RESIN_MOLDING_BUTTON: 0, FINSHING_AGENT_BUTTON: 1, STOP_BUTTON: 2, } # 控件名称映射表 button_name_map = { RESIN_MOLDING_BUTTON: "素面操作按钮", FINSHING_AGENT_BUTTON: "烫金操作按钮", STOP_BUTTON: "紧急停止按钮", } def send_command(command): ''' 发送控制命令到网络继电器, 参数: command: 十六进制字符串,控制指令 返回: 设备响应数据(字节类型),失败返回 False ''' # 将十六进制字符串转换为字节数据并发送 byte_data = binascii.unhexlify(command) # 创建套接字并连接到继电器 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: try: sock.connect((HOST, PORT)) sock.send(byte_data) # 接收响应 response = sock.recv(1024) print(f"收到响应: {binascii.hexlify(response)}") # 校验响应 return response except Exception as e: print(f"通信错误: {e}") return False def get_all_button_status(command_type='button'): ''' 获取所有按钮的当前状态 参数: command_type: 读取类型,默认为 'button' 返回: 字典,键为按钮名称,值为 True/False,失败返回空字典 ''' # 获取对应的读取命令 command = read_status_command.get(command_type) if not command: print(f"未知的读取类型: {command_type}") return {} response = send_command(command) status_dict = {} # 校验响应是否有效(至少10字节) if response and len(response) >= 10: # 状态信息存储在响应的第10个字节(索引9) status_byte = response[9] # 状态在第10字节 # 将字节转换为8位二进制字符串,并反转使低位在前 status_bin = f"{status_byte:08b}"[::-1] if command_type == 'button': bit_map = button_bit_map name_map = button_name_map else: print("不支持的映射类型") return{} # 解析每个按钮的状态 for key, bit_index in bit_map.items(): # 检查对应位是否为1(1表示开启,0表示关闭) state = status_bin[bit_index] == '1' status_dict[key] = state else: print("读取状态失败或响应无效") return status_dict def get_button_status(button_name, command_type='button'): ''' 获取单个控件的当前状态 参数: device_name: 控件名称,如 RESIN_MOLDING_BUTTON、FINSHING_AGENT_BUTTON、STOP_BUTTON command_type: 读取类型,默认为 'button' 返回: True: 开启, False: 关闭, None: 无法读取 ''' status = get_all_button_status(command_type) return status.get(button_name, None) def open(resin_molding_button=False, finishing_agent_button=False, stop_button=False): ''' 打开指定的按钮(仅在按钮当前处于关闭状态时才执行) 参数: resin_molding_button: 素面操作按钮,默认为 False finishing_agent_button: 烫金操作按钮,默认为 False stop_button: 紧急停止按钮,默认为 False ''' status = get_all_button_status() if resin_molding_button and not status.get(RESIN_MOLDING_BUTTON, False): print("打开素面操作按钮") send_command(valve_commands[RESIN_MOLDING_BUTTON]['open']) time.sleep(0.05) if finishing_agent_button and not status.get(FINSHING_AGENT_BUTTON, False): print("打开烫金操作按钮") send_command(valve_commands[FINSHING_AGENT_BUTTON]['open']) time.sleep(0.05) if stop_button and not status.get(STOP_BUTTON, False): print("打开紧急操作按钮") send_command(valve_commands[STOP_BUTTON]['open']) time.sleep(0.05) def close(resin_molding_button=False, finishing_agent_button=False, stop_button=False): ''' 关闭指定的按钮(仅在按钮当前处于开启状态时才执行) 参数: resin_molding_button: 素面操作按钮,默认为 False finishing_agent_button: 烫金操作按钮,默认为 False stop_button: 紧急停止按钮,默认为 False ''' status = get_all_button_status() if resin_molding_button and status.get(RESIN_MOLDING_BUTTON, True): print("关闭素面操作按钮") send_command(valve_commands[RESIN_MOLDING_BUTTON]['close']) time.sleep(0.05) if finishing_agent_button and status.get(FINSHING_AGENT_BUTTON, True): print("关闭烫金操作按钮") send_command(valve_commands[FINSHING_AGENT_BUTTON]['close']) time.sleep(0.05) if stop_button and status.get(STOP_BUTTON, True): print("关闭紧急操作按钮") send_command(valve_commands[STOP_BUTTON]['close']) time.sleep(0.05) def start_press(): # 操作按钮需要先打开后立即关闭 open(resin_molding_button=True) time.sleep(0.5) close(resin_molding_button=True) # if __name__ == '__main__': # # 操作按钮需要先打开后立即关闭 # open(resin_molding_button=True) # time.sleep(0.5) # close(resin_molding_button=True)