This commit is contained in:
2026-01-16 15:21:54 +08:00
parent 69361c5d5b
commit 1fd14cf7d8
41 changed files with 1133 additions and 26131 deletions

View File

@ -4,7 +4,9 @@ import socket
import binascii
import time
import threading
from datetime import datetime
import logging
from typing import Optional
from PySide6.QtCore import Signal, QObject
import numpy as np
from pandas.core.arrays import boolean
@ -133,6 +135,7 @@ class RelayController(QObject):
self.sensor2_ready = False #默认不打开
self.motor_stopped_by_sensor2 = True
self.is_drop_35=False #是否是35码
# ===================== 基础通信方法 =====================
def send_command(self, command_hex, retry_count=2, source='unknown'):
@ -142,11 +145,15 @@ class RelayController(QObject):
byte_data = binascii.unhexlify(command_hex)
for attempt in range(retry_count):
try:
# begin_time=time.time()
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.settimeout(10)
sock.settimeout(1)
sock.connect((self.host, self.port))
sock.send(byte_data)
response = sock.recv(1024)
# end_time=time.time()
# print(f"({source}) 耗时: {end_time-begin_time:.3f}秒")
# hex_response = binascii.hexlify(response).decode('utf-8')
#if source == 'sensor':
#print(f"[传感器响应] {hex_response}")
@ -158,7 +165,7 @@ class RelayController(QObject):
except Exception as e:
self.log_signal.emit(logging.INFO,f"网络继电器通信错误 ({source}): {e}, 尝试重连... ({attempt + 1}/{retry_count})")
print(f"网络继电器通信错误 ({source}): {e}, 尝试重连... ({attempt + 1}/{retry_count})")
time.sleep(5)
time.sleep(1)
self.trigger_alarm()
return None
@ -221,7 +228,7 @@ class RelayController(QObject):
print(f"[{command_type}] 无法获取响应数据")
return responses
def get_emergency_is_pressed(self)->bool:
def get_emergency_is_pressed(self):
"获取急停信号DI 3 位为1正常DI 3为0时为按下急停状态00000000000401020107 后四位01表示一个字节最后一位07二进制对应开关量"
"按下急停为"
command = self.read_status_command.get("sensors")
@ -233,6 +240,7 @@ class RelayController(QObject):
status_crc=response[8]
loc_is_pressed =status_crc==1 and (status_byte & 0b100) == 0 # 0b100 表示第三位为1
else:
loc_is_pressed=None
self.log_signal.emit(logging.ERROR,f"网络继电器[急停] 读取状态失败或响应无效")
print(f"网络继电器[急停] 读取状态失败或响应无效")
@ -267,6 +275,37 @@ class RelayController(QObject):
time.sleep(self.sensor1_loop_delay)
return False
def is_valid_sensor_signal_stable(self, sensor_name, detection_duration=3.0, stability_duration=2.5, check_interval=0.1):
"""
检测在指定时间窗口内是否存在持续稳定的有效信号
参数:
sensor_name: 传感器名称
detection_duration: 总检测时间窗口(秒)默认为3秒
stability_duration: 信号需要持续稳定的时间(秒)默认为2.5秒
check_interval: 检测间隔(秒)默认为0.1秒
返回:
True: 在时间窗口内检测到持续稳定的有效信号
False: 未检测到持续稳定的有效信号
"""
stable_start_time = None # 记录首次检测到有效信号的时间
start_time = time.time()
if not self.is_valid_sensor(sensor_name):
return False # 传感器状态无效,返回
else:
stable_start_time = time.time() # 首次检测到有效信号
time.sleep(check_interval)
while time.time() - start_time < detection_duration:
temp_is_valid = self.is_valid_sensor(sensor_name)
if temp_is_valid:
if time.time() - stable_start_time >= stability_duration:
return True # 信号持续稳定达到要求时间
else:
stable_start_time = time.time() # 信号不稳定,重置计时
time.sleep(check_interval)
return False
def is_valid_sensor_status_1(self, sensor_name):
stable_count = 0
for _ in range(int(self.sensor_stable_duration / self.sensor2_loop_delay)):
@ -337,36 +376,110 @@ class RelayController(QObject):
time.sleep(self.sensor2_loop_lost)
return False
def is_valid_sensor_signal_stable(self, sensor_name, detection_duration=3.0, stability_duration=2.5, check_interval=0.1):
def is_valid_sensor_nowait(self,sensor_name):
"""
测在指定时间窗口内是否存在持续稳定的有效信号
查传感器状态是否有效,不等待,如果第一次没有信号不等待,有信号一起一秒钟
参数:
sensor_name: 传感器名称
detection_duration: 总检测时间窗口(秒)默认为3秒
stability_duration: 信号需要持续稳定的时间(秒)默认为2.5秒
check_interval: 检测间隔(秒)默认为0.1秒
返回:
True: 在时间窗口内检测到持续稳定的有效信号
False: 未检测到持续稳定的有效信号
True: 传感器状态有效
False: 传感器状态无效
"""
stable_start_time = None # 记录首次检测到有效信号的时间
start_time = time.time()
if not self.is_valid_sensor(sensor_name):
return False # 传感器状态无效,返回
else:
stable_start_time = time.time() # 首次检测到有效信号
time.sleep(check_interval)
while time.time() - start_time < detection_duration:
temp_is_valid = self.is_valid_sensor(sensor_name)
if temp_is_valid:
if time.time() - stable_start_time >= stability_duration:
return True # 信号持续稳定达到要求时间
stable_count = 0
_try_nums=5 # 尝试次数
for _num in range(_try_nums):
responses = self.get_all_sensor_responses('sensors')
response = responses.get(sensor_name)
if not response:
print(f"[警告] 无法获取 {sensor_name} 的响应,尝试重试...")
return False
else:
stable_start_time = None # 信号不稳定,重置计时
time.sleep(check_interval)
temp_status_code = self.parse_status_code(response)
if temp_status_code in self.required_codes_1:
stable_count += 1
if stable_count >= 3:
return True
else:
if _num==0:
#首次没有信号,直接返回
return False
else:
stable_count = 0
time.sleep(self.sensor2_loop_lost)
return False
def is_valid_sensor_stable(self,sensor_name):
"""
检查传感器状态是否有效
参数:
sensor_name: 传感器名称
返回:
True: 传感器状态有效
False: 传感器状态无效
"""
#检测一秒钟,首次没有信号直接返回
if not self.is_valid_sensor_nowait(sensor_name):
return False
#需要增加超时时间,否则会一直等待
stable_count = 0
_try_nums=10 # 尝试次数
for _ in range(_try_nums):
responses = self.get_all_sensor_responses('sensors')
response = responses.get(sensor_name)
if response:
temp_status_code = self.parse_status_code(response)
if temp_status_code in self.required_codes_1:
stable_count += 1
print(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]}:检测到信号,已检测 {stable_count}")
if stable_count >= 8:
return True
else:
print(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]}:未检测到信号,已检测 {stable_count}")
else:
print(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]}:[警告] 无法获取 {sensor_name} 的响应,尝试重试...")
# else:
# stable_count = 0
time.sleep(self.sensor2_loop_delay)
return False
# def is_valid_sensor_signal_stable(self, sensor_name, detection_duration=3.0, stability_duration=2.5, check_interval=0.1):
# """
# 检测在指定时间窗口内是否存在持续稳定的有效信号
# 参数:
# sensor_name: 传感器名称
# detection_duration: 总检测时间窗口(秒)默认为3秒
# stability_duration: 信号需要持续稳定的时间(秒)默认为2.5秒
# check_interval: 检测间隔(秒)默认为0.1秒
# 返回:
# True: 在时间窗口内检测到持续稳定的有效信号
# False: 未检测到持续稳定的有效信号
# """
# stable_start_time = None # 记录首次检测到有效信号的时间
# stable_end_time = None # 记录最后检测到有效信号的时间
# start_time = time.time()
# if not self.is_valid_sensor_single(sensor_name):
# return False # 传感器状态无效,返回
# else:
# stable_start_time = time.time() # 首次检测到有效信号
# # stable_end_time = stable_start_time # 最后检测到有效信号
# time.sleep(check_interval)
# while time.time() - start_time < detection_duration:
# #1s时间
# temp_is_valid = self.is_valid_sensor_single(sensor_name)
# if temp_is_valid:
# stable_start_time=time.time()
# else:
# stable_start_time = None # 信号不稳定,重置计时
# # time.sleep(check_interval)
# if stable_start_time - start_time >= stability_duration:
# return True # 信号持续稳定达到要求时间
# else:
# return False
# ===================== 动作控制方法 =====================
def open(self, conveyor1=False, pusher=False, conveyor2=False, clamp=False, pusher1=False, conveyor2_reverse=False,belt=False,alarm=False,blow_sensor2=False):
# if Constant.DebugPosition:
@ -380,7 +493,7 @@ class RelayController(QObject):
time.sleep(self.delay_pusher)
if conveyor2:
self.send_command(self.valve_commands[self.CONVEYOR2]['open'])
time.sleep(self.delay_conveyor)
# time.sleep(0.01)
if clamp:
self.send_command(self.valve_commands[self.CLAMP]['open'])
time.sleep(self.delay_clamp)
@ -409,10 +522,10 @@ class RelayController(QObject):
time.sleep(self.delay_pusher)
if conveyor2:
self.send_command(self.valve_commands[self.CONVEYOR2]['close'])
time.sleep(self.delay_conveyor)
#time.sleep(self.delay_conveyor)
if clamp:
self.send_command(self.valve_commands[self.CLAMP]['close'])
time.sleep(self.delay_clamp)
time.sleep(0.05)
if pusher1:
self.send_command(self.valve_commands[self.PUSHER1]['close'])
time.sleep(self.delay_pusher)
@ -496,11 +609,18 @@ class RelayController(QObject):
_is_pause_close=True
try:
if _is_signal or self.is_valid_sensor_status_1(self.SENSOR2):
# if _is_signal or self.is_valid_sensor_status_1(self.SENSOR2):
#motor_stopped_by_sensor2=False(在滚动的时候)才去检测信号,否则如果后面的料子
#有信号了不会在FPhoto后开滚筒
if (not self.motor_stopped_by_sensor2) and (_is_signal or self.is_valid_sensor_stable(self.SENSOR2)):
#检测到信号,如果之前是没有信号,关闭滚筒
print('检查到sensor2信号')
#print('检查到sensor2信号')
if _is_signal and self.is_valid_sensor2_status_lost(self.SENSOR2):
print('检查到sensor2信号消失')
self.log_signal.emit(logging.INFO,"检查到sensor2信号消失")
if self.is_drop_35:
time.sleep(3.5)
self.open(conveyor2_reverse=True)
time.sleep(2.5)
self.close(conveyor2=True)
#滚筒关闭标志
self.motor_stopped_by_sensor2 = True
@ -512,21 +632,23 @@ class RelayController(QObject):
if self.sensor2_ready:
#只有在FPhoto处才有效
_is_signal=True
if self.motor_stopped_by_sensor2:
print('开滚筒')
self.open(conveyor2=True)
self.motor_stopped_by_sensor2 = False
# if self.motor_stopped_by_sensor2:
# self.log_signal.emit(logging.INFO,"开滚筒2")
# print('开滚筒2开滚筒2开滚筒2开滚筒2')
# self.open(conveyor2=True)
# self.motor_stopped_by_sensor2 = False
# time.sleep(0.1)
time.sleep(0.01)
continue
elif self.sensor2_ready:
#sensor2_ready:通过Feeding:FPhoto处控制是否启动
if self.motor_stopped_by_sensor2:
print('开滚筒')
self.log_signal.emit(logging.INFO,"开滚筒1")
print('开滚筒1开滚筒1开滚筒1开滚筒1')
self.open(conveyor2=True)
self.motor_stopped_by_sensor2 = False
time.sleep(2)
time.sleep(0.5)
except Exception as e:
print(f"SENSOR2 处理错误: {e}")
self.log_signal.emit(logging.ERROR,f"SENSOR2 处理错误: {e}")
@ -546,6 +668,13 @@ class RelayController(QObject):
"""开启皮带"""
self.open(belt=True)
def set_drop_35(self,is_drop_35):
"""
设置是否是35码
is_drop_35:True是False否
"""
self.is_drop_35=is_drop_35
def stop_sensor(self,sensor1_thread,sensor2_thread):
if not self._running:
@ -561,12 +690,15 @@ class RelayController(QObject):
def handle_emergency_pressed(self):
"处理急停按钮信号状态线程"
print('检查急停按钮状态1')
#print('检查急停按钮状态1')
while self._running:
try:
print('检查急停按钮状态')
#print('检查急停按钮状态')
loc_is_pressed =self.get_emergency_is_pressed()
if loc_is_pressed is None:
time.sleep(0.5)
continue
if loc_is_pressed:
# 处理急停按钮信号状态
if not self.emergency_is_pressed:
@ -575,11 +707,11 @@ class RelayController(QObject):
self.emergency_is_pressed=True
self.emergency_signal.emit(True)
else:
print('急停按钮未被按下')
#print('急停按钮未被按下')
self.emergency_is_pressed=False
self.emergency_signal.emit(False)
time.sleep(0.5)
except Exception as e:
print(f"急停 处理错误: {e}")
self.log_signal.emit(logging.ERROR,f"急停线程 处理错误: {e}")
time.sleep(2)
time.sleep(1)

412
EMV/EMV_HC.py Normal file
View File

@ -0,0 +1,412 @@
import socket
import binascii
import time
from datetime import datetime
import logging
class RelayController:
"""
测试传感器2信号情况
"""
def __init__(self, host='192.168.0.18', port=50000):
super().__init__()
# ===================== 全局线程延时参数 =====================
self.sensor1_loop_delay = 0.1 # SENSOR1 线程轮询间隔(秒)
self.sensor1_error_delay = 1.0 # SENSOR1 出错或暂停时延时(秒)
self.sensor1_post_action_delay = 0.2 # SENSOR1 每次循环后延时(秒)
self.sensor2_loop_delay = 0.2 # SENSOR2 线程轮询间隔(秒)
self.sensor2_loop_lost=0.1 # SENSOR2 线程轮询间隔(秒)
# self.sensor2_loop_delay = 0.5 # SENSOR2 线程轮询间隔(秒)
self.sensor2_error_delay = 0.5 # SENSOR2 出错时延时(秒)
self.sensor2_post_action_delay = 0.2 # SENSOR2 每次循环后延时(秒)
# ===================== 全局动作延时参数 =====================
self.delay_conveyor = 0.5 # 传送带开/关动作延时(一半时间,我在控制程序和线程都加了一样的延时)
self.delay_pusher = 0.05 # 推板开/关动作延时
self.delay_clamp = 0.5 # 夹爪动作延时
self.delay_after_pusher = 5.0 # 推板推出后到重启传动带时间
self.emergency_is_pressed=False
# ===================== 传感器稳定检测参数 =====================
self.sensor_stable_duration = 1.0 # 传感器状态稳定检测时间(秒)
self.sensor_max_attempts = 3 # 连续检测次数达到此值判定有效
self.sensor1_debounce_time = 1.0 # 传感器1防抖时间
# ===================== 网络与设备映射 =====================
self.host = host
self.port = port
self.CONVEYOR1 = 'conveyor1'
self.PUSHER = 'pusher'
self.CONVEYOR2 = 'conveyor2'
self.CONVEYOR2_REVERSE = 'conveyor2_reverse'
self.CLAMP = 'clamp'
self.PUSHER1 = 'pusher1'
self.SENSOR1 = 'sensor1'
self.SENSOR2 = 'sensor2'
self.BELT = 'belt'
self.ALARM = 'alarm'
self.BLOW_SENSOR2 = 'blow_sensor2'
self.valve_commands = {
#包装机皮带
self.CONVEYOR1: {'open': '000000000006010500070000', 'close': '00000000000601050007FF00'},
# self.CONVEYOR11: {'open': '00000000000601050000FF00', 'close': '000000000006010500000000'},
self.PUSHER: {'open': '00000000000601050001FF00', 'close': '000000000006010500010000'},
#滚筒2000 0012正转2000 0022 2001变频器频率调整 2000正反转。
self.CONVEYOR2: {'open': '000100000006020620000012', 'close': '000100000006020620000001'},
#DO4
self.CLAMP: {'open': '00000000000601050003FF00', 'close': '000000000006010500030000'},
#DO5 回 DO2推
self.PUSHER1: {'open': '00000000000601050004FF00', 'close': '000000000006010500040000'},
#D07 长皮带
self.BELT: {'open': '00000000000601050006FF00', 'close': '000000000006010500060000'},
#D01 声控报警
self.ALARM: {'open': '00000000000601050000FF00', 'close': '000000000006010500000000'},
#DO6 吹传感器2
self.BLOW_SENSOR2: {'open': '00000000000601050005FF00', 'close': '000000000006010500050000'},
#滚筒反转
self.CONVEYOR2_REVERSE: {'open': '000100000006020620000022', 'close': '000100000006020620000001'}
}
#devices:读取继点器的状态
#sensors 传感器的状态 D12
self.read_status_command = {
'devices': '000000000006010100000008',
'sensors': '000000000006010200000008'
}
self.device_bit_map = {
self.CONVEYOR1: 0,
self.PUSHER: 1,
self.CONVEYOR2: 2,
self.CLAMP: 3,
self.PUSHER1: 4,
self.CONVEYOR2_REVERSE: 5,
self.BELT: 6,
self.ALARM: 7,
#self.BLOW_SENSOR2: 8
}
self.sensor_bit_map = {
self.SENSOR1: 0,
self.SENSOR2: 1,
}
self.device_name_map = {
self.CONVEYOR1: "包装机皮带",
self.PUSHER: "推板开",
self.CONVEYOR2: "滚筒",
self.CLAMP: "机械臂夹爪",
self.PUSHER1: "推板关",
self.CONVEYOR2_REVERSE: "滚筒反转",
self.BELT: "皮带",
self.ALARM: "声控报警",
self.BLOW_SENSOR2: "吹传感器2"
}
self.sensor_name_map = {
self.SENSOR1: '位置传感器1',
self.SENSOR2: '位置传感器2',
}
# ===================== 状态控制变量 =====================
self._running = False #线程运行标识
self._ispause = False #线程暂停标识
self._sensor1_thread = None
self._sensor2_thread = None
self.required_codes = {'0101', '0103','0105','0107'} # 有效状态码传感器1
self.required_codes_1 = {'0102', '0103','0106','0107'} # 有效状态码传感器2
self.sensor1_triggered = False
self.sensor1_last_time = 0
self.sensor2_ready = False #默认不打开
self.motor_stopped_by_sensor2 = True
# ===================== 基础通信方法 =====================
def send_command(self, command_hex, retry_count=2, source='unknown'):
byte_data = binascii.unhexlify(command_hex)
for attempt in range(retry_count):
try:
# begin_time=time.time()
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.settimeout(1)
sock.connect((self.host, self.port))
sock.send(byte_data)
response = sock.recv(1024)
# end_time=time.time()
# print(f"({source}) 耗时: {end_time-begin_time:.3f}秒")
# hex_response = binascii.hexlify(response).decode('utf-8')
#if source == 'sensor':
#print(f"[传感器响应] {hex_response}")
#elif source == 'device':
#print(f"[设备控制响应] {hex_response}")
#else:
#print(f"[通信响应] {hex_response}")
return response
except Exception as e:
self.log_signal.emit(logging.INFO,f"网络继电器通信错误 ({source}): {e}, 尝试重连... ({attempt + 1}/{retry_count})")
print(f"网络继电器通信错误 ({source}): {e}, 尝试重连... ({attempt + 1}/{retry_count})")
time.sleep(1)
self.trigger_alarm()
return None
def trigger_alarm(self):
self.log_signal.emit(logging.ERROR,"警告:网络继电器连续多次通信失败,请检查设备连接!")
print("警告:网络继电器连续多次通信失败,请检查设备连接!")
# ===================== 状态读取方法 =====================
def get_all_device_status(self, command_type='devices'):
# if Constant.DebugPosition:
# return {self.SENSOR2:True}
command = self.read_status_command.get(command_type)
if not command:
print(f"未知的网络继电器读取类型: {command_type}")
return {}
source = 'sensor' if command_type == 'sensors' else 'device'
response = self.send_command(command, source=source)
status_dict = {}
if response and len(response) >= 10:
status_byte = response[9]
status_bin = f"{status_byte:08b}"[::-1]
bit_map = self.device_bit_map if command_type == 'devices' else self.sensor_bit_map
# name_map = self.device_name_map if command_type == 'devices' else self.sensor_name_map
for key, bit_index in bit_map.items():
status_dict[key] = status_bin[bit_index] == '1'
else:
print(f"网络继电器[{command_type}] 读取状态失败或响应无效")
return status_dict
def get_all_sensor_responses(self, command_type='sensors'):
"""
获取所有传感器的原始 Modbus 响应字符串
示例:{'sensor1': '00000000000401020101', 'sensor2': '00000000000401020100'}
"""
command = self.read_status_command.get(command_type)
if not command:
print(f"未知的读取类型: {command_type}")
return {}
source = 'sensor' if command_type == 'sensors' else 'device'
response = self.send_command(command, source=source)
responses = {}
if response and len(response) >= 10:
hex_response = binascii.hexlify(response).decode('utf-8')
# print(f"[原始响应][{command_type}] {hex_response}")
# 假设传感器数据从第 9 字节开始,长度为 2 字节
for name, bit_index in self.sensor_bit_map.items():
offset = 9 + (bit_index // 8)
bit_pos = bit_index % 8
byte = response[offset]
status = (byte >> bit_pos) & 1
responses[name] = hex_response
else:
print(f"[{command_type}] 无法获取响应数据")
return responses
def parse_status_code(self, response):
"""
从 Modbus 响应字符串中提取状态码(后两位)
示例00000000000401020101 -> '01'
"""
if isinstance(response, str) and len(response) >= 18:
return response[16:20]
return None
def is_valid_sensor_status(self, sensor_name):
stable_count = 0
for _ in range(int(self.sensor_stable_duration / self.sensor1_loop_delay)):
responses = self.get_all_sensor_responses('sensors')
response = responses.get(sensor_name)
if not response:
stable_count = 0
else:
status_code = self.parse_status_code(response)
if status_code in self.required_codes:
stable_count += 1
if stable_count >= self.sensor_max_attempts:
return True
else:
stable_count = 0
time.sleep(self.sensor1_loop_delay)
return False
def is_valid_sensor_signal_stable(self, sensor_name, detection_duration=3.0, stability_duration=2.5, check_interval=0.1):
"""
检测在指定时间窗口内是否存在持续稳定的有效信号
参数:
sensor_name: 传感器名称
detection_duration: 总检测时间窗口(秒)默认为3秒
stability_duration: 信号需要持续稳定的时间(秒)默认为2.5秒
check_interval: 检测间隔(秒)默认为0.1秒
返回:
True: 在时间窗口内检测到持续稳定的有效信号
False: 未检测到持续稳定的有效信号
"""
stable_start_time = None # 记录首次检测到有效信号的时间
start_time = time.time()
if not self.is_valid_sensor(sensor_name):
return False # 传感器状态无效,返回
else:
stable_start_time = time.time() # 首次检测到有效信号
time.sleep(check_interval)
while time.time() - start_time < detection_duration:
temp_is_valid = self.is_valid_sensor(sensor_name)
if temp_is_valid:
if time.time() - stable_start_time >= stability_duration:
return True # 信号持续稳定达到要求时间
else:
stable_start_time = time.time() # 信号不稳定,重置计时
time.sleep(check_interval)
return False
def is_valid_sensor_status_1(self, sensor_name):
stable_count = 0
for _ in range(int(self.sensor_stable_duration / self.sensor2_loop_delay)):
responses = self.get_all_sensor_responses('sensors')
response = responses.get(sensor_name)
if not response:
print(f"[警告] 无法获取 {sensor_name} 的响应,尝试重试...")
stable_count = 0
else:
status_code = self.parse_status_code(response)
if status_code in self.required_codes_1:
stable_count += 1
if stable_count >= self.sensor_max_attempts:
return True
else:
stable_count = 0
time.sleep(self.sensor2_loop_delay)
return False
def is_valid_sensor2_status_lost(self, sensor_name):
stable_count = 0
_try_nums=5 # 尝试次数
for _ in range(_try_nums):
responses = self.get_all_sensor_responses('sensors')
response = responses.get(sensor_name)
if not response:
print(f"[警告] 无法获取 {sensor_name} 的响应,尝试重试...")
stable_count = 0
else:
status_code = self.parse_status_code(response)
if status_code not in self.required_codes_1:
stable_count += 1
if stable_count >= self.sensor_max_attempts:
return True
else:
stable_count = 0
time.sleep(self.sensor2_loop_lost)
return False
def is_valid_sensor(self,sensor_name):
"""
检查传感器状态是否有效
参数:
sensor_name: 传感器名称
返回:
True: 传感器状态有效
False: 传感器状态无效
"""
stable_count = 0
_try_nums=5 # 尝试次数
for _ in range(_try_nums):
responses = self.get_all_sensor_responses('sensors')
response = responses.get(sensor_name)
if not response:
print(f"[警告] 无法获取 {sensor_name} 的响应,尝试重试...")
return False
else:
temp_status_code = self.parse_status_code(response)
if temp_status_code in self.required_codes_1:
stable_count += 1
if stable_count >= 3:
return True
else:
stable_count = 0
time.sleep(self.sensor2_loop_lost)
return False
def is_valid_sensor_stable(self,sensor_name):
"""
检查传感器状态是否有效
参数:
sensor_name: 传感器名称
返回:
True: 传感器状态有效
False: 传感器状态无效
"""
if not self.is_valid_sensor(sensor_name):
return False
#需要增加超时时间,否则会一直等待
stable_count = 0
_try_nums=10 # 尝试次数
for _ in range(_try_nums):
responses = self.get_all_sensor_responses('sensors')
response = responses.get(sensor_name)
if response:
temp_status_code = self.parse_status_code(response)
if temp_status_code in self.required_codes_1:
stable_count += 1
print(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]}:检测到信号,已检测 {stable_count}")
if stable_count >= 8:
return True
else:
print(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]}:未检测到信号,已检测 {stable_count}")
else:
print(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]}:[警告] 无法获取 {sensor_name} 的响应,尝试重试...")
# else:
# stable_count = 0
time.sleep(self.sensor2_loop_delay)
return False
if __name__ == "__main__":
# logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# 配置日志同时输出到控制台与文件
log_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
file_handler = logging.FileHandler('relay_controller.log', encoding='utf-8')
file_handler.setLevel(logging.INFO)
file_handler.setFormatter(log_formatter)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
console_handler.setFormatter(log_formatter)
logger = logging.getLogger()
logger.setLevel(logging.INFO)
logger.addHandler(file_handler)
logger.addHandler(console_handler)
relay_controller = RelayController()
_count=0
while True:
responses = relay_controller.get_all_sensor_responses('sensors')
response = responses.get('sensor2')
if response:
temp_status_code = relay_controller.parse_status_code(response)
if temp_status_code in relay_controller.required_codes_1:
_count+=1
logger.info(f"检测到信号,连续 {_count}")
else:
_count=0
logger.info(f"未检测到信号")
else:
logger.info(f"[警告] 无法获取响应")
time.sleep(0.2)

View File

@ -1,401 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
import binascii
import time
import threading
import logging
from PySide6.QtCore import Signal, QObject
import numpy as np
class RelayController:
need_origin_signal = Signal(str)
take_no_photo_sigal = Signal()
update_detect_image = Signal(np.ndarray)
log_signal = Signal(int, str)
def __init__(self, host='192.168.0.18', port=50000):
self.host = host
self.port = port
# 控件映射
self.CONVEYOR1 = 'conveyor1'
self.PUSHER = 'pusher'
self.CONVEYOR2 = 'conveyor2'
self.CLAMP = 'clamp'
self.PUSHER1 = 'pusher1'
self.SENSOR1 = 'sensor1'
self.SENSOR2 = 'sensor2'
self.valve_commands = {
self.CONVEYOR1: {'open': '00000000000601050000FF00', 'close': '000000000006010500000000'},
self.PUSHER: {'open': '00000000000601050001FF00', 'close': '000000000006010500010000'},
#self.CONVEYOR2: {'open': '00000000000601050002FF00', 'close': '000000000006010500020000'},
self.CONVEYOR2: {'open': '000100000006020620000012', 'close': '000100000006020620000001'},
self.CLAMP: {'open': '00000000000601050003FF00', 'close': '000000000006010500030000'},
self.PUSHER1: {'open': '00000000000601050004FF00', 'close': '000000000006010500040000'}#
}
self.read_status_command = {
'devices': '000000000006010100000008',
'sensors': '000000000006010200000008'
}
self.device_bit_map = {
self.CONVEYOR1: 0,
self.PUSHER: 1,
self.CONVEYOR2: 2,
self.CLAMP: 3,
self.PUSHER1: 4,
}
self.sensor_bit_map = {
self.SENSOR1: 0,
self.SENSOR2: 1,#
}
self.device_name_map = {
self.CONVEYOR1: "传送带1",
self.PUSHER: "推板开",
self.CONVEYOR2: "传送带2",
self.CLAMP: "机械臂夹爪",
self.PUSHER1: "推板关",
}
self.sensor_name_map = {
self.SENSOR1: '位置传感器1',
self.SENSOR2: '位置传感器2',
}
# 传感器状态变量
self._running = False
self._sensor1_thread = None
self._sensor2_thread = None
# 配置项
self.required_codes = {'0101', '0103'} # 有效状态码
self.required_codes_1 = { '0102', '0103'} # 有效状态码(需要修改)
self.stable_duration = 1.0 # 稳定检测时间(秒)
self.max_attempts = 3 # 连续检测次数
self.poll_interval = 0.2 # 检测间隔
# 状态锁和防抖
self.sensor1_triggered = False
self.sensor1_last_time = 0
self.sensor1_debounce = 2.0
# 传感器2状态变量
self.sensor2_ready = True
self.motor_stopped_by_sensor2 = False
def send_command(self, command_hex, retry_count=2, source='unknown'):
byte_data = binascii.unhexlify(command_hex)
for attempt in range(retry_count):
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.settimeout(10)
sock.connect((self.host, self.port))
sock.send(byte_data)
response = sock.recv(1024)
hex_response = binascii.hexlify(response).decode('utf-8')
#if source == 'sensor':
#print(f"[传感器响应] {hex_response}")
#elif source == 'device':
#print(f"[设备控制响应] {hex_response}")
#else:
#print(f"[通信响应] {hex_response}")
return response
except Exception as e:
print(f"通信错误 ({source}): {e}, 尝试重连... ({attempt + 1}/{retry_count})")
time.sleep(5)
self.trigger_alarm()
return None
def trigger_alarm(self):
print("警告:连续多次通信失败,请检查设备连接!")
def get_all_device_status(self, command_type='devices'):
command = self.read_status_command.get(command_type)
if not command:
print(f"未知的读取类型: {command_type}")
return {}
source = 'sensor' if command_type == 'sensors' else 'device'
response = self.send_command(command, source=source)
status_dict = {}
if response and len(response) >= 10:
status_byte = response[9]
status_bin = f"{status_byte:08b}"[::-1]
bit_map = self.device_bit_map if command_type == 'devices' else self.sensor_bit_map
name_map = self.device_name_map if command_type == 'devices' else self.sensor_name_map
for key, bit_index in bit_map.items():
status_dict[key] = status_bin[bit_index] == '1'
else:
print(f"[{command_type}] 读取状态失败或响应无效")
return status_dict
def get_all_sensor_responses(self, command_type='sensors'):
"""
获取所有传感器的原始 Modbus 响应字符串
示例:{'sensor1': '00000000000401020101', 'sensor2': '00000000000401020100'}
"""
command = self.read_status_command.get(command_type)
if not command:
print(f"未知的读取类型: {command_type}")
return {}
source = 'sensor' if command_type == 'sensors' else 'device'
response = self.send_command(command, source=source)
responses = {}
if response and len(response) >= 10:
hex_response = binascii.hexlify(response).decode('utf-8')
print(f"[原始响应][{command_type}] {hex_response}")
# 假设传感器数据从第 9 字节开始,长度为 2 字节
for name, bit_index in self.sensor_bit_map.items():
offset = 9 + (bit_index // 8)
bit_pos = bit_index % 8
byte = response[offset]
status = (byte >> bit_pos) & 1
responses[name] = hex_response
else:
print(f"[{command_type}] 无法获取响应数据")
return responses
def parse_status_code(self, response):
"""
从 Modbus 响应字符串中提取状态码(后两位)
示例00000000000401020101 -> '01'
"""
if isinstance(response, str) and len(response) >= 18:
return response[16:20]
return None
def is_valid_sensor_status(self, sensor_name: object) -> object:
"""
检查传感器是否在稳定时间内连续返回有效状态码01 或 03
"""
stable_count = 0
for _ in range(int(self.stable_duration / self.poll_interval)):
responses = self.get_all_sensor_responses('sensors')
response = responses.get(sensor_name)
if not response:
print(f"[警告] 无法获取 {sensor_name} 的响应,尝试重试...")
stable_count = 0
else:
status_code = self.parse_status_code(response)
if status_code in self.required_codes:
stable_count += 1
if stable_count >= self.max_attempts:
return True
else:
stable_count = 0
print(f"[警告] {sensor_name} 状态码无效: {status_code}")
time.sleep(self.poll_interval)
return False
def is_valid_sensor_status_1(self, sensor_name: object) -> object:
"""
检查传感器是否在稳定时间内连续返回有效状态码01 或 03
"""
stable_count = 0
for _ in range(int(self.stable_duration / self.poll_interval)):
responses = self.get_all_sensor_responses('sensors')
response = responses.get(sensor_name)
if not response:
print(f"[警告] 无法获取 {sensor_name} 的响应,尝试重试...")
stable_count = 0
else:
status_code = self.parse_status_code(response)
if status_code in self.required_codes_1:
stable_count += 1
if stable_count >= self.max_attempts:
return True
else:
stable_count = 0
print(f"[警告] {sensor_name} 状态码无效: {status_code}")
time.sleep(self.poll_interval)
return False
def open(self, conveyor1=False, pusher=False, conveyor2=False, clamp=False, pusher1=False):
status = self.get_all_device_status()
if conveyor1 and not status.get(self.CONVEYOR1, False):
print("打开传送带1")
self.send_command(self.valve_commands[self.CONVEYOR1]['open'], source='device')
time.sleep(1)
if pusher and not status.get(self.PUSHER, False):
print("打开推板")
self.send_command(self.valve_commands[self.PUSHER]['open'], source='device')
time.sleep(0.05)
if conveyor2 and not status.get(self.CONVEYOR2, False):
print("打开传送带2")
self.send_command(self.valve_commands[self.CONVEYOR2]['open'], source='device')
time.sleep(1)
if clamp and not status.get(self.CLAMP, False):
print("启动机械臂抓夹")
self.send_command(self.valve_commands[self.CLAMP]['open'], source='device')
time.sleep(0.5)
if pusher1 and not status.get(self.PUSHER1, False):
print("关闭推板")
self.send_command(self.valve_commands[self.PUSHER1]['open'], source='device')
time.sleep(0.05)
def close(self, conveyor1=False, pusher=False, conveyor2=False, clamp=False, pusher1=False):
status = self.get_all_device_status()
if conveyor1 :
#if conveyor1 and status.get(self.CONVEYOR1, True):
print("关闭传送带1")
self.send_command(self.valve_commands[self.CONVEYOR1]['close'], source='device')
time.sleep(1)
if pusher :
#if pusher and status.get(self.PUSHER, True):
print("关闭推板")
self.send_command(self.valve_commands[self.PUSHER]['close'], source='device')
time.sleep(0.05)
if conveyor2 :
#if conveyor2 and status.get(self.CONVEYOR2, True):
print("关闭传送带2")
self.send_command(self.valve_commands[self.CONVEYOR2]['close'], source='device')
time.sleep(1)
if clamp :
#if clamp and status.get(self.CLAMP, True):
print("停止机械臂抓夹")
self.send_command(self.valve_commands[self.CLAMP]['close'], source='device')
time.sleep(0.5)
if pusher1 :
#if pusher and status.get(self.PUSHER1, True):
print("关闭推板_1")
self.send_command(self.valve_commands[self.PUSHER1]['close'], source='device')
time.sleep(0.05)
def handle_sensor1(self):
while self._running:
try:
# 检查传感器是否返回有效状态码01 或 03
if self.is_valid_sensor_status(self.SENSOR1):
current_time = time.time()
# 判断是否已触发 或 是否在防抖时间内
if not self.sensor1_triggered and (current_time - self.sensor1_last_time) > self.sensor1_debounce:
print("✅ SENSOR1 检测到有效信号,开始执行推料流程")
# 标记已触发,防止重复执行
self.sensor1_triggered = True
self.sensor1_last_time = current_time
# 1. 停止包装机皮带电机(关闭)
self.close(conveyor1=True)
time.sleep(0.5)
# 2. 推板开启
self.open(pusher=True)
time.sleep(0.1)
self.close(pusher=True)
# 2结束
time.sleep(3) # 保持 3 秒
# 3. 包装机皮带电机开启
self.open(conveyor1=True)
time.sleep(0.5)
# 4. 推板关闭
#self.close(pusher=True)
self.open(pusher1=True)
time.sleep(0.1)
self.close(pusher1=True)
time.sleep(1)
# 5. 状态检查(可选)
status = self.get_all_device_status()
if status.get('conveyor1') and not status.get('pusher'):
print("🟢流程完成1皮带运行中推板已收回")
else:
print("⚠️ 状态异常,请检查设备")
# 流程结束,重置触发标志
self.sensor1_triggered = False
# 如果传感器无效,确保触发标志可重置(可选)
time.sleep(0.2)
except Exception as e:
print(f"SENSOR1 处理错误: {e}")
self.sensor1_triggered = False
time.sleep(1)
#传感器2检测到料包 → 立即停止 conveyor2」这个逻辑 放在传感器线程中处理
def handle_sensor2(self):
while self._running:
try:
# 检测传感器2状态
#self.sensor2_ready = None
if self.is_valid_sensor_status_1(self.SENSOR2):
print("✅ SENSOR2 检测到有效信号,开始执行关闭滚筒电机流程")
if not self.sensor2_ready:
#self.log_signal.emit(logging.INFO, "🟢 传感器2检测到料包到位立即停止 conveyor2")
# ✅ 立即停止电机(不管机器人是否在抓取)
self.close(conveyor2=True)
print("执行关闭")
self.motor_stopped_by_sensor2 = True # 标记为传感器2触发停止
self.sensor2_ready = True
else:
if self.sensor2_ready and self.motor_stopped_by_sensor2:
#self.log_signal.emit(logging.INFO, "🟡 传感器2未检测到料包准备重新启动 conveyor2")
# ✅ 重新启动 conveyor2可选
self.open(conveyor2=True)
self.motor_stopped_by_sensor2 = False
self.sensor2_ready = False
time.sleep(0.5)
except Exception as e:
self.log_signal.emit(logging.ERROR, f"🔴 SENSOR2 处理错误: {e}")
time.sleep(1)
def start(self):
if self._running:
print("线程已经在运行")
return
print("启动传感器线程")
self._running = True
self._sensor1_thread = threading.Thread(target=self.handle_sensor1, daemon=True)
self._sensor2_thread = threading.Thread(target=self.handle_sensor2, daemon=True)
self._sensor1_thread.start()
self._sensor2_thread.start()
def stop(self):
if not self._running:
print("线程未在运行")
return
print("停止传感器线程")
self._running = False
if self._sensor1_thread:
self._sensor1_thread.join()
if self._sensor2_thread:
self._sensor2_thread.join()
print("传感器线程已终止。")
def start_sensor1_only(self):
if self._running:
print("传感器线程已经在运行")
return
print("启动传感器1监听线程...")
self._running = True
self._sensor1_thread = threading.Thread(target=self.handle_sensor1, daemon=True)
self._sensor1_thread.start()
if __name__ == '__main__':
controller = RelayController()
controller.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
controller.stop()

View File

@ -1,274 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
import binascii
import time
import threading
class RelayController:
def __init__(self, host='192.168.0.18', port=50000):
self.host = host
self.port = port
# 控件映射
self.CONVEYOR1 = 'conveyor1'
self.PUSHER = 'pusher'
self.CONVEYOR2 = 'conveyor2'
self.CLAMP = 'clamp'
self.SENSOR1 = 'sensor1'
self.SENSOR2 = 'sensor2'
self.valve_commands = {
self.CONVEYOR1: {'open': '00000000000601050000FF00', 'close': '000000000006010500000000'},
self.PUSHER: {'open': '00000000000601050001FF00', 'close': '000000000006010500010000'},
self.CONVEYOR2: {'open': '00000000000601050002FF00', 'close': '000000000006010500020000'},
self.CLAMP: {'open': '00000000000601050003FF00', 'close': '000000000006010500030000'}
}
self.read_status_command = {
'devices': '000000000006010100000008',
'sensors': '000000000006010200000008'
}
self.device_bit_map = {
self.CONVEYOR1: 0,
self.PUSHER: 1,
self.CONVEYOR2: 2,
self.CLAMP: 3,
}
self.sensor_bit_map = {
self.SENSOR1: 0,
self.SENSOR2: 1,
}
self.device_name_map = {
self.CONVEYOR1: "传送带1",
self.PUSHER: "推板",
self.CONVEYOR2: "传送带2",
self.CLAMP: "机械臂"
}
self.sensor_name_map = {
self.SENSOR1: '位置传感器1',
self.SENSOR2: '位置传感器2',
}
self._running = False
self._sensor1_thread = None
self._sensor2_thread = None
def send_command_old(self, command_hex):
byte_data = binascii.unhexlify(command_hex)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
try:
sock.connect((self.host, self.port))
sock.send(byte_data)
response = sock.recv(1024)
print(f"收到响应: {binascii.hexlify(response)}")
return response
except Exception as e:
print(f"通信错误: {e}")
return None
def start_sensor1_only(self):
if self._running:
print("线程已经在运行")
return
print("启动传感器1监听线程")
self._running = True
self._sensor1_thread = threading.Thread(target=self.handle_sensor1, daemon=True)
self._sensor1_thread.start()
def send_command(self, command_hex, retry_count=5, source='unknown'):
byte_data = binascii.unhexlify(command_hex)
for attempt in range(retry_count):
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.settimeout(10)
sock.connect((self.host, self.port))
sock.send(byte_data)
response = sock.recv(1024)
hex_response = binascii.hexlify(response).decode('utf-8')
# 根据 source 区分响应来源
if source == 'sensor':
print(f"[传感器响应] {hex_response}")
elif source == 'device':
print(f"[设备控制响应] {hex_response}")
else:
print(f"[通信响应] {hex_response}")
return response
except Exception as e:
print(f"通信错误 ({source}): {e}, 尝试重连... ({attempt + 1}/{retry_count})")
if attempt == retry_count - 1:
self.trigger_alarm()
time.sleep(5)
return None
def trigger_alarm(self):
"""当通信错误超过最大重试次数时触发报警"""
print("警告:连续多次通信失败,请检查设备连接!")
# 这里可以添加更多的报警措施,如发送邮件、短信或声音警报等
def get_all_device_status(self, command_type='devices'):
command = self.read_status_command.get(command_type)
if not command:
print(f"未知的读取类型: {command_type}")
return {}
# 设置来源标识
source = 'sensor' if command_type == 'sensors' else 'device'
response = self.send_command(command, source=source)
status_dict = {}
if response and len(response) >= 10:
status_byte = response[9]
status_bin = f"{status_byte:08b}"[::-1]
bit_map = self.device_bit_map if command_type == 'devices' else self.sensor_bit_map
name_map = self.device_name_map if command_type == 'devices' else self.sensor_name_map
for key, bit_index in bit_map.items():
status_dict[key] = status_bin[bit_index] == '1'
else:
print(f"[{command_type}] 读取状态失败或响应无效")
return status_dict
def get_device_status_old(self, name, command_type='devices'):
return self.get_all_device_status(command_type).get(name, None)
def get_device_status(self, name, command_type='devices', stable_duration=1.0, max_attempts=3):
"""
获取指定设备/传感器的状态,只有在连续稳定检测到信号后才返回 True。
参数:
name (str): 设备/传感器名称,如 SENSOR1
command_type (str): 类型,'devices''sensors'
stable_duration (float): 信号需要稳定的持续时间(秒)
max_attempts (int): 最大尝试次数(用于稳定性判断)
返回:
bool or None: 稳定检测到信号返回 True否则返回 False 或 None失败
"""
stable_count = 0
interval = 0.2 # 每隔多久检查一次
for _ in range(int(stable_duration / interval)):
statuses = self.get_all_device_status(command_type)
status = statuses.get(name)
if status is True:
stable_count += 1
if stable_count >= max_attempts:
return True
elif status is False:
return False
else:
# None 表示读取失败
print(f"[警告] 读取 {name} 状态失败,尝试重试...")
stable_count = 0
time.sleep(interval)
return False # 默认返回 False避免误触发
def open(self, conveyor1=False, pusher=False, conveyor2=False, clamp=False):
status = self.get_all_device_status()
if conveyor1 and not status.get(self.CONVEYOR1, False):
print("打开传送带1")
self.send_command(self.valve_commands[self.CONVEYOR1]['open'], source='device')
time.sleep(1)
if pusher and not status.get(self.PUSHER, False):
print("打开推板")
self.send_command(self.valve_commands[self.PUSHER]['open'], source='device')
time.sleep(0.05)
if conveyor2 and not status.get(self.CONVEYOR2, False):
print("打开传送带2")
self.send_command(self.valve_commands[self.CONVEYOR2]['open'], source='device')
time.sleep(1)
if clamp and not status.get(self.CLAMP, False):
print("启动机械臂抓夹")
self.send_command(self.valve_commands[self.CLAMP]['open'], source='device')
time.sleep(0.5)
def close(self, conveyor1=False, pusher=False, conveyor2=False, clamp=False):
status = self.get_all_device_status()
if conveyor1 and status.get(self.CONVEYOR1, True):
print("关闭传送带1")
self.send_command(self.valve_commands[self.CONVEYOR1]['close'], source='device')
time.sleep(1)
if pusher and status.get(self.PUSHER, True):
print("关闭推板")
self.send_command(self.valve_commands[self.PUSHER]['close'], source='device')
time.sleep(0.05)
if conveyor2 and status.get(self.CONVEYOR2, True):
print("关闭传送带2")
self.send_command(self.valve_commands[self.CONVEYOR2]['close'], source='device')
time.sleep(1)
if clamp and status.get(self.CLAMP, True):
print("停止机械臂抓夹")
self.send_command(self.valve_commands[self.CLAMP]['close'], source='device')
time.sleep(0.5)
def handle_sensor1(self):
while self._running:
try:
if self.get_device_status(self.SENSOR1, 'sensors'):
print("SENSOR1 检测到信号,执行流程")
self.close(conveyor1=True)
time.sleep(2)
self.open(pusher=True)
time.sleep(5)
self.close(pusher=True)
time.sleep(2)
self.open(conveyor1=True)
time.sleep(0.5)
except Exception as e:
print(f"SENSOR1 处理错误: {e}")
def handle_sensor2(self):
while self._running:
try:
if self.get_device_status(self.SENSOR2, 'sensors'):
print("SENSOR2 检测到信号,执行流程")
self.close(conveyor2=True)
time.sleep(2)
self.open(clamp=True)
time.sleep(2)
self.open(conveyor2=True)
time.sleep(0.5)
except Exception as e:
print(f"SENSOR2 处理错误: {e}")
def start(self):
if self._running:
print("线程已经在运行")
return
print("启动传感器线程")
self._running = True
self._sensor1_thread = threading.Thread(target=self.handle_sensor1, daemon=True)
self._sensor2_thread = threading.Thread(target=self.handle_sensor2, daemon=True)
self._sensor1_thread.start()
self._sensor2_thread.start()
def stop(self):
if not self._running:
print("线程未在运行")
return
print("停止传感器线程")
self._running = False # 设置标志位为 False
if self._sensor1_thread is not None:
self._sensor1_thread.join() # 等待线程结束
if self._sensor2_thread is not None:
self._sensor2_thread.join()
print("传感器线程已终止。")

View File

@ -4,6 +4,7 @@ import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
from EMV import RelayController
import time
from datetime import datetime
import threading
relay_controller = RelayController() # 实例化控制器
@ -97,17 +98,39 @@ if __name__ == "__main__":
# sensors = relay_controller.get_all_device_status()
# print(sensors)
# time.sleep(3)
# test_device('conveyor2', 'open')
while True:
test_device('conveyor2', 'open')
# test_device('belt', 'close')
# time.sleep(3)
test_device('conveyor2', 'close')
# test_device('belt', 'close')
# time.sleep(3)
# test_device('conveyor2', 'open')
# test_device('belt', 'close')
# sensors = relay_controller.get_all_device_status('sensors')
# sensor2_value = sensors.get(relay_controller.SENSOR2, False)
# while True:
# responses = relay_controller.get_all_sensor_responses('sensors')
# response = responses.get(relay_controller.SENSOR2)
# if not response:
# print(f"[警告] 无法获取 {relay_controller.SENSOR2} 的响应,尝试重试...")
# else:
# status_code = relay_controller.parse_status_code(response)
# if status_code in relay_controller.required_codes_1:
# print(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]+'收到有效状态码信号')
# else:
# print(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]+'无效状态码信号')
# time.sleep(0.2)
# relay_controller._running=True
# relay_controller.sensor2_ready=True
# relay_controller.handle_sensor2()
test_device('blow_sensor2', 'close')
# test_device('blow_sensor2', 'open')
# test_device('blow_sensor2', 'close')
# while True:
@ -132,7 +155,7 @@ if __name__ == "__main__":
# relay_controller._running=True
# relay_controller.handle_emergency_pressed()
time.sleep(100)
time.sleep(1000000)
print('aaaaa')

View File

@ -1,28 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
from EMV import RelayController # 请根据你的实际模块名修改
def run_real_sensor_monitor():
# 创建控制器实例
controller = RelayController()
try:
print("启动传感器1监听线程...")
controller.start_sensor1_only() # 只启动传感器1的监听线程
print("开始监听真实传感器1信号按 Ctrl+C 停止...")
# 主线程可以继续做其他事情,或者只是等待
while True:
time.sleep(1) # 保持主线程运行
except KeyboardInterrupt:
print("\n检测到中断信号,正在停止传感器监听...")
finally:
controller.stop()
print("程序已安全退出。")
if __name__ == '__main__':
run_real_sensor_monitor()

View File

@ -1,88 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
import logging
from threading import Thread
from unittest.mock import patch
# 假设你的 RelayController 类在名为 EMV 的模块中
from EMV import RelayController # 替换为你的模块名
# 设置日志格式
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
def simulate_sensor(controller, sensor_name, active=True, duration=10):
"""
模拟指定传感器在一段时间内处于激活状态。
:param controller: RelayController 实例
:param sensor_name: 要模拟的传感器名(如 controller.SENSOR2
:param active: 是否激活传感器信号
:param duration: 模拟运行时间(秒)
"""
logging.info(f"🧪 开始模拟传感器:{controller.sensor_name_map.get(sensor_name, sensor_name)}")
original_method = controller.get_all_device_status
def mock_get_all_device_status(command_type='devices'):
if command_type == 'sensors':
all_status = original_method(command_type)
all_status[sensor_name] = active
return all_status
return original_method(command_type)
# 确定目标函数
target_func = None
if sensor_name == controller.SENSOR1:
target_func = controller.handle_sensor1
elif sensor_name == controller.SENSOR2:
target_func = controller.handle_sensor2
else:
raise ValueError("不支持的传感器名称")
# 设置 _running 为 True确保线程能进入循环
controller._running = True
# 启动线程
sensor_thread = Thread(target=target_func, daemon=True)
sensor_thread.start()
logging.info(f"{controller.sensor_name_map[sensor_name]} 监听线程已启动")
try:
# Patch get_all_device_status 方法
with patch.object(controller, 'get_all_device_status', mock_get_all_device_status):
logging.info(f"🟢 模拟 {controller.sensor_name_map[sensor_name]} 有信号输入,持续 {duration}")
time.sleep(duration)
except Exception as e:
logging.error(f"🔴 模拟过程中发生错误: {e}")
finally:
# 停止控制器
controller._running = False
logging.info("🛑 停止控制器主循环")
# 等待线程退出
sensor_thread.join(timeout=2)
if sensor_thread.is_alive():
logging.warning("⚠️ 传感器线程未能及时退出")
else:
logging.info("✅ 传感器线程已安全退出")
if __name__ == '__main__':
# 创建控制器实例
relay_controller = RelayController()
# 打印当前配置的传感器名称映射(方便调试)
logging.info("🔧 当前传感器配置:")
for key, val in relay_controller.sensor_name_map.items():
logging.info(f" {key}: {val}")
try:
# 模拟 SENSOR2 有信号输入,运行 10 秒
logging.info("🧪 开始模拟传感器2")#修改这里
simulate_sensor(relay_controller, relay_controller.SENSOR1, active=True, duration=10)#
# 可选:模拟 SENSOR1
# logging.info("🧪 开始模拟传感器1")
# simulate_sensor(relay_controller, relay_controller.SENSOR1, active=True, duration=10)
except KeyboardInterrupt:
logging.info("🛑 用户中断模拟")
finally:
logging.info("🏁 模拟结束")