diff --git a/UI/BlockParameterManageWidget.py b/UI/BlockParameterManageWidget.py index 8e14e97..5c8fc75 100644 --- a/UI/BlockParameterManageWidget.py +++ b/UI/BlockParameterManageWidget.py @@ -49,7 +49,7 @@ class TbCombox(QComboBox): def initUI(self): # 创建ComboBox - self.addItems(["压力转换块", "温度转换块", "物位转换块", "流量转换块"]) + self.addItems(["压力转换块", "温度转换块", "物位转换块", "流量转换块", 'WIKA液位计']) self.setEditable(True) # 设置为可编辑以应用样式表隐藏文本 self.setObjectName('tbcombox') @@ -79,8 +79,8 @@ class DynamicAddBlock(QHBoxLayout): self.blockViewlist = [] self.tbtypeList = TbtypeList #存放转换块的各种类型 # print(self.tbtypeList) - self.tbList = ['PressureTranslationBlock', 'TemperatureTranslationBlock', 'LevelTranslationBlock', 'FlowTranslationBlock'] #存放四个转换块 - self.enumList = [TBType.pressureTB, TBType.tempTB, TBType.levelTB, TBType.flowTB] + self.tbList = ['PressureTranslationBlock', 'TemperatureTranslationBlock', 'LevelTranslationBlock', 'FlowTranslationBlock', 'WiKaLevelTranslationBlock'] #存放四个转换块 + self.enumList = [TBType.pressureTB, TBType.tempTB, TBType.levelTB, TBType.flowTB, TBType.wikaLevelTB] self.initUI() def initUI(self): @@ -88,6 +88,7 @@ class DynamicAddBlock(QHBoxLayout): tbNumber = self.blocklist[1] fbNumber = self.blocklist[2] + for i in range(pbNumber): pblockBtn = QPushButton('物理块') @@ -113,7 +114,7 @@ class DynamicAddBlock(QHBoxLayout): fblockBtn.setObjectName("parameBtn") fblockBtn.setIcon(qtawesome.icon('fa.th-large', color='#1fbb6f')) fblockBtn.clicked.connect(lambda _, fbbtn = fblockBtn: self.switchParameterWidget(fbbtn)) - # self.addWidget(fblockBtn, 3) + self.addWidget(fblockBtn, 3) self.buttonlist.append(fblockBtn) aiFunctionBlockView = ParmView(AIFunctionBlock, i, BlockType.FB) self.blockViewlist.append(aiFunctionBlockView) @@ -140,6 +141,13 @@ class DynamicAddBlock(QHBoxLayout): case TBType.flowTB: tbcombox.setCurrentIndex(3) tblockBtn = QPushButton(tbcombox.currentText() + str(i + 1)) + + case None: + tbcombox.setCurrentIndex(4) + tblockBtn = QPushButton(tbcombox.currentText() + str(i + 1)) + print(1) + + # tbcombox.setCurrentIndex(0) # tblockBtn = QPushButton('压力转换块' + str(i + 1)) @@ -160,6 +168,7 @@ class DynamicAddBlock(QHBoxLayout): tbBlockView = ParmView(globals()[tb], i, enum) self.blockViewlist.append(tbBlockView) + self.parameterButtonGroup = QButtonGroup() self.parameterButtonGroup.setExclusive(True) for button in self.buttonlist: @@ -181,8 +190,8 @@ class DynamicAddBlock(QHBoxLayout): buttonNumber = button.text()[-1] button.setText(tbType + str(buttonNumber)) if button.isChecked(): - stackIndex = (int(self.blocklist[0]) + int(self.blocklist[2]) + index) + (int(buttonNumber) - 1) * 4 - + stackIndex = (int(self.blocklist[0]) + int(self.blocklist[2]) + index) + (int(buttonNumber) - 1) * 5 + print(stackIndex) self.parameStackWidget.setCurrentIndex(stackIndex) @@ -276,46 +285,62 @@ class BlockParameterManageWidget(QWidget): self.setLayout(self.mainlayout) def loadBlackData(self): + address = self.deviceAddressEdit.text() + # print(address) + if address: + pattern = re.compile(r'^(?:[1-9]|[1-9][0-9]|1[0-1][0-9]|12[0-7])$') + match = pattern.match(address) + + else: + reply = QMessageBox.question(self.parent(), + '警告', + "请输入从站地址", + QMessageBox.Yes) + return + + if not match: + QMessageBox.warning(self, '提示', '请输入2 - 127。') + return + if self.initUIstat: - address = self.deviceAddressEdit.text() - # print(address) - if address: - pattern = re.compile(r'^(?:[1-9]|[1-9][0-9]|1[0-1][0-9]|12[0-7])$') - match = pattern.match(address) - if not match: - QMessageBox.warning(self, '提示', '请输入2 - 127。') - return - if self.initUIstat: - try: - - self.blockManage = BlockManage(self._isPa, int(address)) - - except Exception as e: - reply = QMessageBox.question(self.parent(), - '警告', - f"发生错误: {e}", - QMessageBox.Yes) - return - self.splitter.deleteLater() - self.widget.deleteLater() - self.splitter = QSplitter() - Globals.setValue('blockManage', self.blockManage) - blocklist = self.blockManage.getBlockNums() - self.blockLayout = DynamicAddBlock(blocklist, self.blockManage.TBTypeList) - self.settingLayout.addLayout(self.blockLayout, 7) - self.settingLayout.addWidget(self.splitter, 11) - self.mainlayout.addWidget(self.blockLayout.parameStackWidget, 20) - self.initUIstat = False - else: + try: + + self.blockManage = BlockManage(self._isPa, int(address)) + + except Exception as e: reply = QMessageBox.question(self.parent(), - '警告', - "请输入从站地址", - QMessageBox.Yes) + '警告', + f"发生错误: {e}", + QMessageBox.Yes) return + self.splitter.deleteLater() + self.widget.deleteLater() + self.splitter = QSplitter() + Globals.setValue('blockManage', self.blockManage) + blocklist = self.blockManage.getBlockNums() + self.blockLayout = DynamicAddBlock(blocklist, self.blockManage.TBTypeList) + self.settingLayout.addLayout(self.blockLayout, 7) + self.settingLayout.addWidget(self.splitter, 11) + self.mainlayout.addWidget(self.blockLayout.parameStackWidget, 20) + self.initUIstat = False + self.recordAddress = address #记录链接成功的站地址 + else: reply = QMessageBox.question(self, '确定', '确定更换站地址吗?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: + try: + + self.blockManage = BlockManage(self._isPa, int(address)) + + except Exception as e: + reply = QMessageBox.question(self.parent(), + '警告', + f"发生错误: {e}", + QMessageBox.Yes) + self.deviceAddressEdit.setText(self.recordAddress) + return + self.blockLayout.deleteLater() self.splitter.deleteLater() self.splitter = QSplitter() @@ -326,6 +351,7 @@ class BlockParameterManageWidget(QWidget): self.settingLayout.addLayout(self.blockLayout, 7) self.settingLayout.addWidget(self.splitter, 11) self.mainlayout.addWidget(self.blockLayout.parameStackWidget, 20) + self.recordAddress = address #记录链接成功的站地址 else: return diff --git a/UI/EditAddressWidget.py b/UI/EditAddressWidget.py index fb7e606..b780fde 100644 --- a/UI/EditAddressWidget.py +++ b/UI/EditAddressWidget.py @@ -179,6 +179,7 @@ class EditAddressWidget(QDialog): return identNumber = self.GSDData[self.deviceTypeCombox.currentIndex()]['identNumber'] + print(identNumber) oldAddress = int(oldAddress) newAddress = int(newAddress) result = self.DPV1Master.editDevAddress(oldAddress, newAddress, identNumber) diff --git a/UI/MainWindow.py b/UI/MainWindow.py index 100381d..82455ad 100644 --- a/UI/MainWindow.py +++ b/UI/MainWindow.py @@ -109,11 +109,18 @@ class MainWindow(QWidget): self.switchBtn = QPushButton('通讯组态') self.switchBtn.setObjectName("switchBtn") - self.switchBtn.setIcon(qtawesome.icon('fa.exchange', color='#1fbb6f')) + self.switchBtn.setIcon(qtawesome.icon('msc.circuit-board', color='#1fbb6f')) self.switchBtn.setIconSize(QSize(25, 25)) self.switchBtn.setCheckable(True) self.switchBtn.clicked.connect(self.switchWidget) + self.valueBtn = QPushButton('变量读写') + self.valueBtn.setObjectName("switchBtn") + self.valueBtn.setIcon(qtawesome.icon('fa.pencil', color='#1fbb6f')) + self.valueBtn.setIconSize(QSize(25, 25)) + self.valueBtn.setCheckable(True) + + self.deviceParameterManageBtn = QPushButton('设备参数管理') self.deviceParameterManageBtn.setObjectName('deviceParameterManageBtn') self.deviceParameterManageBtn.setIcon(qtawesome.icon('fa.gears', color='#1fbb6f')) @@ -160,6 +167,7 @@ class MainWindow(QWidget): toolbarLayout.addWidget(iconLabel, 1) toolbarLayout.addWidget(QWidget(), 1) toolbarLayout.addWidget(self.startProtocolBtn, 1) + toolbarLayout.addWidget(self.valueBtn, 1) toolbarLayout.addWidget(self.switchBtn, 1) toolbarLayout.addWidget(self.switchTouchBtn, 1) toolbarLayout.addWidget(self.deviceParameterManageBtn, 1) @@ -203,6 +211,7 @@ class MainWindow(QWidget): self.stackWidget.addWidget(self.upperWidget) self.stackWidget.addWidget(QWidget()) self.stackWidget.addWidget(self.blockParameterManageWidget) + self.valueBtn.clicked.connect(lambda : self.stackWidget.setCurrentIndex(0)) self.mainLayout = QVBoxLayout(self) self.mainLayout.addLayout(toolbarLayout, 1) @@ -283,30 +292,26 @@ class MainWindow(QWidget): def searchSlave(self): address = self.dpv1Master.searchSlave() + if address == '读取错误': + self.dpv1Master = DPV1Master('192.168.3.10', 502) + self.addressLabel.setText('在线仪表地址:') self.addressLabel.setText('在线仪表地址:{}'.format(address)) - def switchWidget(self): - if self.switchBtn.isChecked(): - if self.process: - self.stackWidget.setCurrentIndex(1) - QTimer.singleShot(50, lambda:self.stackWidget.setCurrentIndex(3)) - else: - self.stackWidget.setCurrentIndex(1) - startupInfo = subprocess.STARTUPINFO() - startupInfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW - startupInfo.wShowWindow = 2 - self.process = subprocess.Popen("D:\\EnTalk PROFIBUS Manager\\DP.exe",startupinfo=startupInfo) - QTimer.singleShot(500, lambda:self.showLowerWidget(self.process)) - self.switchBtn.setText('变量读写') - self.showMaximized() - # self.switchBtn.setIcon(QIcon(':/static/varMagH.png')) + + if self.process: + self.stackWidget.setCurrentIndex(1) + QTimer.singleShot(50, lambda:self.stackWidget.setCurrentIndex(3)) else: - # self.stackWidget.setCurrentIndex(1) - self.stackWidget.setCurrentIndex(0) - self.switchBtn.setText('通讯组态') - # self.switchBtn.setIcon(QIcon(':/static/newH.png')) + self.stackWidget.setCurrentIndex(1) + startupInfo = subprocess.STARTUPINFO() + startupInfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + startupInfo.wShowWindow = 2 + self.process = subprocess.Popen("D:\\EnTalk PROFIBUS Manager\\DP.exe",startupinfo=startupInfo) + QTimer.singleShot(500, lambda:self.showLowerWidget(self.process)) + self.showMaximized() + # self.switchBtn.setIcon(QIcon(':/static/varMagH.png')) def switchDeviceParManageWidget(self): diff --git a/model/ClientModel/Client.py b/model/ClientModel/Client.py index bf8bd9a..8f5abf0 100644 --- a/model/ClientModel/Client.py +++ b/model/ClientModel/Client.py @@ -18,6 +18,6 @@ class Client(object): else: self.deviceDB = SqliteDatabase(dbPath) client_proxy.initialize(self.deviceDB) - modelsArr = [DeviceDB, PressureTranslationBlock, PhysicalBlock, AIFunctionBlock, TemperatureTranslationBlock, LevelTranslationBlock, FlowTranslationBlock, UnitTable] + modelsArr = [DeviceDB, PressureTranslationBlock, PhysicalBlock, AIFunctionBlock, TemperatureTranslationBlock, LevelTranslationBlock, FlowTranslationBlock, WiKaLevelTranslationBlock, UnitTable] self.deviceDB.connect() self.deviceDB.create_tables(modelsArr, safe = True) diff --git a/model/ProjectModel/BlockManage.py b/model/ProjectModel/BlockManage.py index 530b994..5f4f5d4 100644 --- a/model/ProjectModel/BlockManage.py +++ b/model/ProjectModel/BlockManage.py @@ -39,6 +39,7 @@ class TBType(Enum): tempTB = -2 levelTB = -3 # 物位转换块 pressureTB = -4 + wikaLevelTB = -5 class BlockManage(): _instance = None @@ -73,6 +74,7 @@ class BlockManage(): def initBlocks(self): # print(self._isPa,5555) if not self.DPV1Master.judgeSlave(self.address): + print(self.address) raise RuntimeError(f"连接从站{self.address}失败.") self.blockDict = { BlockType.PB : [], @@ -117,7 +119,7 @@ class BlockManage(): else: data = self.DPV1Master.readParm(address = self.address, slot = 1, index = key, length = 4 * value) # print(data, int(len(data)/2)) - print(data) + # print(data) data = struct.unpack('>{}h'.format(int(len(data)/2)), data) tuples = [(data[i], data[i+1]) for i in range(0, len(data), 2)] entryTuples += tuples @@ -213,6 +215,7 @@ class Block(): TBType.pressureTB: PressureTranslationBlock.getallParame, TBType.tempTB: TemperatureTranslationBlock.getallParame, TBType.levelTB: LevelTranslationBlock.getallParame, + TBType.wikaLevelTB: WiKaLevelTranslationBlock.getallParame }.get(self.blockType, lambda: []) parmsData = getParmsFunc() diff --git a/protocol/ModBus/DPV1Master.py b/protocol/ModBus/DPV1Master.py index 3c43d0c..0c5af61 100644 --- a/protocol/ModBus/DPV1Master.py +++ b/protocol/ModBus/DPV1Master.py @@ -65,6 +65,8 @@ class DPV1Master(): # self.searchSlaveThread = SearchSlaveThread(callback = callback, master = self) # self.searchSlaveThread.start() data = self.readHoldingRegisters(1, 850, 64) + if data == '读取错误': + return data dataHex = struct.pack('>64h', *data) indices = [i for i, byte in enumerate(dataHex) if byte == 1] return ",".join(map(str, indices)) @@ -123,8 +125,11 @@ class DPV1Master(): return result def judgeSlave(self, address): + # print(type(address)) hexAddress = address.to_bytes(1, byteorder='little') - searchByteStream = b'\x01' + hexAddress + b'\x01\x00\xF0\x00' + searchByteStream = b'\x01' + hexAddress + b'\x01\x01\xF0\x00' + # print(searchByteStream) + searchDate = struct.unpack('>hhh', searchByteStream) self.writeMultipleRegister(1, 750, searchDate) time.sleep(1.1) @@ -133,6 +138,7 @@ class DPV1Master(): # print(dir) self.writeMultipleRegister(1, 750, self.resetData) time.sleep(0.1) + # print(dir) if not self.areAllZeros(dir) and dir != 'error': return True else: @@ -143,8 +149,8 @@ class DPV1Master(): newAddressHex = newAddress.to_bytes(1, byteorder='little') closeProtocolHex = b'\x05\x00' closeProtocolData = struct.unpack('>h', closeProtocolHex) - self.writeMultipleRegister(1, 750, closeProtocolHex) - time.sleep(0.4) + self.writeMultipleRegister(1, 750, closeProtocolData) + time.sleep(1) # print(identNumer) idHighHex = int(identNumer[:2], 16).to_bytes(1, byteorder='little') idLowHex = int(identNumer[2:], 16).to_bytes(1, byteorder='little') @@ -153,6 +159,7 @@ class DPV1Master(): editAddressDate = struct.unpack('>hhhh', editAddressStream) # print(editAddressDate) self.writeMultipleRegister(1, 750, self.resetData) + time.sleep(0.2) self.writeMultipleRegister(1, 750, editAddressDate) time.sleep(0.4) value = self.readHoldingRegisters(1, 750, 2) @@ -160,6 +167,10 @@ class DPV1Master(): result = '修改错误' else: result = '修改成功' + openProtocolHex = b'\x05\x01' + openProtocolData = struct.unpack('>h', openProtocolHex) + self.writeMultipleRegister(1, 750, openProtocolData) + time.sleep(0.2) self.writeMultipleRegister(1, 750, self.resetData) time.sleep(0.1) return result diff --git a/utils/DBModels/DeviceParModels.py b/utils/DBModels/DeviceParModels.py index aeb31e5..7462cf1 100644 --- a/utils/DBModels/DeviceParModels.py +++ b/utils/DBModels/DeviceParModels.py @@ -141,6 +141,18 @@ class FlowTranslationBlock(PressureTranslationBlock): transferType = CharField() description = CharField() createTime = CharField() + +class WiKaLevelTranslationBlock(PressureTranslationBlock): + index = CharField() + paramName = CharField() + objectType = CharField() + dataType = CharField() + saveType = CharField() + dataSize = CharField() + accessType = CharField() + transferType = CharField() + description = CharField() + createTime = CharField() class UnitTable(BaseModel):