From 69446d817a15b38b6821abdc8d75ca369c88423f Mon Sep 17 00:00:00 2001 From: "DESKTOP-3D7M4SA\\Hicent" <452669850@qq.com> Date: Sun, 14 Dec 2025 19:24:07 +0800 Subject: [PATCH] =?UTF-8?q?1214=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- UI/ProfibusWidgets/RightAreaWidget.py | 68 +++++++++++++++++++++++++-- protocol/ProtocolManage.py | 21 +++++++++ protocol/RPC/RpcClient.py | 45 +++++++++++++++++- 3 files changed, 130 insertions(+), 4 deletions(-) diff --git a/UI/ProfibusWidgets/RightAreaWidget.py b/UI/ProfibusWidgets/RightAreaWidget.py index f309105..b22fe04 100644 --- a/UI/ProfibusWidgets/RightAreaWidget.py +++ b/UI/ProfibusWidgets/RightAreaWidget.py @@ -4,6 +4,7 @@ from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QPushButton, QGridLay QHBoxLayout, QMessageBox, QSplitter, QRadioButton from UI.ProfibusWidgets.SoftKeyBoardEdit import SoftKeyBoardEdit +from utils import Globals class ForceButton(QPushButton): def __init__(self, number = None, valueLabel = None, valueEdit = None, qualityValueLabel = None, \ @@ -31,6 +32,7 @@ class RightAreaWidgets(QWidget): self.qualityLabel = {} self.areaWidget = areaWidget self.devicesManange = self.areaWidget.devicesManange + self.protocolManage = Globals.getValue('protocolManage') self.order = order self.byteLineEdit = byteLineEdit self.dataType = dataType @@ -205,6 +207,45 @@ class RightAreaWidgets(QWidget): def readValues(self, curIndex): # print(curIndex) if not self.force: + # 优先通过ProtocolManage读取(这样可以获取RPC同步的值) + if self.valueName and self.protocolManage: + try: + value = self.protocolManage.readVariableValue(self.valueName) + if value is not None: + # 处理从ProtocolManage获取的值 + if isinstance(value, dict) and 'value' in value: + actualValue = value['value'] + qualityValue = value.get('quality', '0x00') + else: + actualValue = value + qualityValue = '0x00' + + # 更新UI显示 + if self.dataType in ['AI', 'AO']: + # 模拟量显示 + if 0 in self.areaLabel: + self.areaLabel[0].setText(str(actualValue)) + if 0 in self.qualityLabel: + self.qualityLabel[0].setText(str(qualityValue)) + else: + # 离散量显示 + for index, label in self.areaLabel.items(): + if isinstance(actualValue, list) and index < len(actualValue): + bitValue = actualValue[index] + if bitValue == 1: + label.setText('ON') + label.setChecked(True) + else: + label.setText('OFF') + label.setChecked(False) + else: + label.setText('OFF') + label.setChecked(False) + return + except Exception as e: + print(f"通过ProtocolManage读取变量 {self.valueName} 失败: {e}") + + # 回退到直接从设备读取 device = self.devicesManange.getDevice(self.deviceName) values, qualityValueList = device.getAreaValues(curIndex) # print(qualityValueList) @@ -225,7 +266,7 @@ class RightAreaWidgets(QWidget): self.areaLabel[index].setText(str(value)) for index, value in enumerate(qualityValueList): self.qualityLabel[index].setText(str(value)) - # print(self.areaLabel[index],values) + # print(self.areaLabel[index],values) @@ -248,7 +289,20 @@ class RightAreaWidgets(QWidget): if valueList is None: return else: - self.devicesManange.writeAreas(deviceName = self.deviceName, areaIndex = curIndex, values = valueList, qualityValueList = qualityValueList) + # 通过ProtocolManage写入,以便触发RPC同步 + if self.valueName and self.protocolManage: + # 构造写入值(包含质量值) + writeValue = { + 'value': float(value), + 'quality': qualityValue + } + success = self.protocolManage.writeVariableValue(self.valueName, writeValue) + if not success: + # 如果ProtocolManage写入失败,回退到直接写入 + self.devicesManange.writeAreas(deviceName = self.deviceName, areaIndex = curIndex, values = valueList, qualityValueList = qualityValueList) + else: + # 如果没有变量名或ProtocolManage不可用,使用直接写入 + self.devicesManange.writeAreas(deviceName = self.deviceName, areaIndex = curIndex, values = valueList, qualityValueList = qualityValueList) def DIDOForceValues(self): @@ -261,7 +315,15 @@ class RightAreaWidgets(QWidget): if valueList is None: return else: - self.devicesManange.writeAreas(deviceName = self.deviceName, areaIndex = curIndex, values = valueList) + # 通过ProtocolManage写入,以便触发RPC同步 + if self.valueName and self.protocolManage: + success = self.protocolManage.writeVariableValue(self.valueName, value) + if not success: + # 如果ProtocolManage写入失败,回退到直接写入 + self.devicesManange.writeAreas(deviceName = self.deviceName, areaIndex = curIndex, values = valueList) + else: + # 如果没有变量名或ProtocolManage不可用,使用直接写入 + self.devicesManange.writeAreas(deviceName = self.deviceName, areaIndex = curIndex, values = valueList) if sender.isChecked(): sender.setText('ON') else: diff --git a/protocol/ProtocolManage.py b/protocol/ProtocolManage.py index bc5d17b..0d73fc6 100644 --- a/protocol/ProtocolManage.py +++ b/protocol/ProtocolManage.py @@ -470,8 +470,10 @@ class ProtocolManage(object): if self._profibusConnected: return True try: + print(f"正在连接Profibus...") self.profibusManager.connect() self._profibusConnected = True + print(f"Profibus连接成功") except Exception as e: print(f"连接PROFIBUS失败: {e}") self._profibusConnected = False @@ -485,40 +487,53 @@ class ProtocolManage(object): if not force and (now - self._profibusLastUpdate) < 0.5: return if not self._ensureProfibusConnected(): + print(f"Profibus连接失败,跳过区域更新") return with self.profibusLock: try: + print(f"正在读取Profibus区域数据...") self.profibusManager.readAreas() self._profibusLastUpdate = now + print(f"Profibus区域数据读取完成") except Exception as e: print(f"读取PROFIBUS区域失败: {e}") def _writeProfibusVariable(self, info, rawValue): if not self.profibusManager: + print(f"Profibus管理器未初始化") return False, None if not self._ensureProfibusConnected(): + print(f"Profibus连接失败") return False, None device = self.profibusManager.getDevice(info['deviceName']) if not device: + print(f"找不到设备: {info['deviceName']}") return False, None areaIndex = info['areaIndex'] if areaIndex >= len(device.areas): + print(f"区域索引超出范围: {areaIndex} >= {len(device.areas)}") return False, None area = device.areas[areaIndex] + print(f"写入设备 {info['deviceName']} 区域 {areaIndex} 类型 {area.type} 值 {rawValue}") + if area.type in ['AI', 'AO']: analogValue, qualityList = self._formatAnalogValue(rawValue) if analogValue is None: + print(f"模拟量值格式化失败") return False, None valuesToWrite = [analogValue] normalizedValue = analogValue else: valuesToWrite = self._formatDiscreteValues(area, rawValue) if valuesToWrite is None: + print(f"离散量值格式化失败") return False, None qualityList = None normalizedValue = valuesToWrite[:] + with self.profibusLock: try: + print(f"调用writeAreas写入数据: {valuesToWrite}") if qualityList is not None: self.profibusManager.writeAreas( deviceName=info['deviceName'], @@ -532,6 +547,7 @@ class ProtocolManage(object): areaIndex=areaIndex, values=valuesToWrite ) + print(f"writeAreas调用成功,更新本地缓存") if area.type in ['AI', 'AO']: area.currentValue = [normalizedValue] if qualityList: @@ -612,15 +628,20 @@ class ProtocolManage(object): def _readProfibusVariable(self, info): if not self.profibusManager: + print(f"Profibus管理器未初始化") return None self._updateProfibusAreas() device = self.profibusManager.getDevice(info['deviceName']) if not device: + print(f"找不到设备: {info['deviceName']}") return None areaIndex = info['areaIndex'] if areaIndex >= len(device.areas): + print(f"区域索引超出范围: {areaIndex} >= {len(device.areas)}") return None area = device.areas[areaIndex] + print(f"读取设备 {info['deviceName']} 区域 {areaIndex} 类型 {area.type} 当前值: {getattr(area, 'currentValue', None)}") + if area.type in ['AI', 'AO']: if isinstance(area.currentValue, list) and area.currentValue: try: diff --git a/protocol/RPC/RpcClient.py b/protocol/RPC/RpcClient.py index 65d6bac..3c72217 100644 --- a/protocol/RPC/RpcClient.py +++ b/protocol/RPC/RpcClient.py @@ -109,7 +109,50 @@ class RpcClient: def handleReadCommand(self): """处理读取命令""" - return {"client": self.clientName, "variables": self.variables} + print(f"[{self.clientName}] 处理读取命令...") + # 合并variables字典和ProtocolManage中已知的变量 + allVariables = dict(self.variables) + print(f"[{self.clientName}] 原始variables数量: {len(allVariables)}") + + # 添加ProtocolManage中已知的变量(特别是Profibus变量) + if self.protocolManager: + allVarNames = self.protocolManager.getAllVariableNames() + print(f"[{self.clientName}] ProtocolManage中总变量数量: {len(allVarNames)}") + for varName in allVarNames: + if varName not in allVariables: + # 实际读取变量的真实值 + try: + value = self.protocolManager.readVariableValue(varName) + print(f"[{self.clientName}] 读取变量 {varName}: {value}") + if value is not None: + varInfo = self.protocolManager.lookupVariable(varName) + if varInfo: + info = varInfo['variableData'] + allVariables[varName] = { + "value": str(value), + "min": info.get('min'), + "max": info.get('max'), + "type": info.get('varType') + } + else: + allVariables[varName] = { + "value": str(value), + "min": None, + "max": None, + "type": None + } + except Exception as e: + print(f"[{self.clientName}] 读取变量 {varName} 失败: {e}") + # 如果读取失败,添加占位符以便existsVar能找到 + allVariables[varName] = { + "value": "0", + "min": None, + "max": None, + "type": None + } + + print(f"[{self.clientName}] 返回变量总数: {len(allVariables)}") + return {"client": self.clientName, "variables": allVariables} def handleWriteCommand(self, request): """处理写入命令"""