diff --git a/Static/PA块信息表.xlsx b/Static/PA块信息表.xlsx index b4a2b2a..534fa52 100644 Binary files a/Static/PA块信息表.xlsx and b/Static/PA块信息表.xlsx differ diff --git a/UI/BlockParameterManageWidget.py b/UI/BlockParameterManageWidget.py index b729efa..b56c858 100644 --- a/UI/BlockParameterManageWidget.py +++ b/UI/BlockParameterManageWidget.py @@ -135,7 +135,6 @@ class DynamicAddBlock(QHBoxLayout): self.parameStackWidget.addWidget(view) def switchParameterWidget(self, buttonType): - for index , button in enumerate(self.buttonlist): if button == buttonType: self.parameStackWidget.setCurrentIndex(index) @@ -271,14 +270,20 @@ class BlockParameterManageWidget(QWidget): return self.loadingDataWidget = LoadingDataWidget() - self.loadingDataWidget.loadData() + self.loadingDataWidget.show() + # self.loadingDataWidget.loadData() blockView = self.blockLayout.parameStackWidget.currentWidget() model = blockView.model - model.updateColumn(5, '查询中sdadadsda\r\nsdasdsasasad\r\nasdsadsad...') - blockView.resizeHeader() - blockName = blockView.blockType + # model.updateColumn(5, '查询中sdadadsda\r\nsdasdsasasad\r\nasdsadsad...') + # blockView.resizeHeader() + blockType = blockView.blockType blcokIndex = blockView.blcokIndex + self.blockManage.getBlockValues(blockType = blockType, blockIndex = blcokIndex, callback = self.loadingDataWidget.loadData, callback2 = model.updateValue) + # print(valueList) + # model.updateValue(valueList) + # print(blockType, blcokIndex) + diff --git a/UI/BlockParameterModel.py b/UI/BlockParameterModel.py index 4dc0d41..ab2da97 100644 --- a/UI/BlockParameterModel.py +++ b/UI/BlockParameterModel.py @@ -30,7 +30,6 @@ class VarTableModel(QAbstractTableModel): def append_data(self, x): - self.datas.append(x) self.checkList = ['Unchecked'] * len(self.datas) self.table.proxy.invalidate() @@ -129,6 +128,12 @@ class VarTableModel(QAbstractTableModel): self.datas[sourceRow], self.datas[destinationChild] = self.datas[destinationChild], self.datas[sourceRow] self.table.proxy.invalidate() + def updateValue(self, valueList): + print(len(valueList), len(self.datas)) + for index, value in enumerate(valueList): + self.datas[index][5] = value + self.table.proxy.invalidate() + class VarButtonDelegate(QItemDelegate): diff --git a/UI/LoadingDataWidget.py b/UI/LoadingDataWidget.py index 65da807..2399855 100644 --- a/UI/LoadingDataWidget.py +++ b/UI/LoadingDataWidget.py @@ -1,7 +1,9 @@ import sys import time from PyQt5.QtWidgets import QApplication, QWidget, QDialog, QVBoxLayout, QPushButton, QLabel, QProgressBar -from PyQt5.QtCore import Qt, QThread, pyqtSignal +from PyQt5.QtCore import Qt, QThread, pyqtSignal, pyqtSlot + +from UI.SearchAddressWidget import CustomProgressBar class LoadDataThread(QThread): progress = pyqtSignal(int) @@ -11,16 +13,18 @@ class LoadDataThread(QThread): time.sleep(0.01) # 模拟数据加载过程 self.progress.emit(i) -class LoadingDialog(QDialog): +class LoadingDataWidget(QDialog): + # loadDataSignal = pyqtSignal(int, int) def __init__(self): super().__init__() self.initUI() + # self.loadDataSignal.connect(self.loadData) def initUI(self): vbox = QVBoxLayout() self.label = QLabel("加载数据中,请稍后...", self) - self.progressBar = QProgressBar(self) + self.progressBar = CustomProgressBar(self) vbox.addWidget(self.label) vbox.addWidget(self.progressBar) @@ -29,27 +33,17 @@ class LoadingDialog(QDialog): self.setWindowTitle('数据查询') self.setWindowFlags(Qt.Window | Qt.WindowTitleHint | Qt.CustomizeWindowHint) self.setModal(True) - - def updateProgress(self, value): + + # def loadSignalEmit(self, maxValue:int, value:int): + # # print(maxValue, value) + # self.loadDataSignal.emit(maxValue, value) + + @pyqtSlot(int, int) + def loadData(self, maxValue:int, value:int): + self.progressBar.setMaximum(maxValue) self.progressBar.setValue(value) - -class LoadingDataWidget(QWidget): - def __init__(self): - super().__init__() - - def loadData(self): - self.loadingDialog = LoadingDialog() - - # 创建和启动数据加载线程 - self.loadThread = LoadDataThread() - self.loadThread.progress.connect(self.loadingDialog.updateProgress) - self.loadThread.finished.connect(self.onLoadingFinished) - - self.loadThread.start() - self.loadingDialog.exec_() - - def onLoadingFinished(self): - self.loadingDialog.accept() + if maxValue == value: + self.accept() if __name__ == '__main__': app = QApplication(sys.argv) diff --git a/UI/SearchAddressWidget.py b/UI/SearchAddressWidget.py index a0b2173..51d4c76 100644 --- a/UI/SearchAddressWidget.py +++ b/UI/SearchAddressWidget.py @@ -19,11 +19,9 @@ class CustomProgressBar(QProgressBar): currentValue = self.value() maxValue = self.maximum() # 返回自定义的显示文本 - return f"{currentValue}/{maxValue}" + return f"正在加载{currentValue}/{maxValue}" - - class SearchAddressWidget(QWidget): def __init__(self, deviceAddressEdit): super().__init__() diff --git a/model/ProjectModel/BlockManage.py b/model/ProjectModel/BlockManage.py index 794f21b..92a9ba0 100644 --- a/model/ProjectModel/BlockManage.py +++ b/model/ProjectModel/BlockManage.py @@ -8,6 +8,27 @@ from utils.DBModels.DeviceParModels import * from protocol.ModBus.DPV1Master import DPV1Master from model.ProjectModel.ParmManage import Parm +import concurrent.futures + +import threading + +from PyQt5.QtCore import pyqtSignal, pyqtSlot, QThread + +class LoadDataThread(QThread): + loadDataSignal = pyqtSignal(int, int) + finished = pyqtSignal(list) + def __init__(self, parent): + super().__init__() + self.parent = parent + + + def run(self): + valueList = [] + for index, parm in enumerate(self.parent.parms): + self.loadDataSignal.emit(len(self.parent.parms), index + 1) + valueList.append(parm.readValue()) + self.finished.emit(valueList) + class BlockType(Enum): TB = 1 PB = 0 @@ -93,8 +114,15 @@ class BlockManage(): # print(blkSlot, blkIndex) # print(self.blockDict) - def getBlockValues(self, blockType, blockIndex): - pass + def getBlockValues(self, blockType, blockIndex, callback, callback2): + if not isinstance(blockType, BlockType): + typ = BlockType.TB + block = self.blockDict[typ][blockIndex] + block.blockType = blockType + block.addParms() + else: + block = self.blockDict[blockType][blockIndex] + return block.getParmsValue(callback, callback2) def getBlockNums(self): return [len(self.blockDict[BlockType.PB]), len(self.blockDict[BlockType.TB]), len(self.blockDict[BlockType.FB])] @@ -110,6 +138,7 @@ class Block(): numParms = None blockIndex = None address = None + loadDataSignal = pyqtSignal(int, int) def __init__(self, blockType, DPV1Master): self.parms = [] self.blockType = blockType @@ -117,10 +146,15 @@ class Block(): # self.addParms() def addParms(self): + self.parms = [] getParmsFunc = { BlockType.PB: PhysicalBlock.getallParame, - BlockType.TB: AIFunctionBlock.getallParame, - BlockType.FB: PressureTranslationBlock.getallParame, + BlockType.TB: PressureTranslationBlock.getallParame, + BlockType.FB: AIFunctionBlock.getallParame, + TBType.flowTB: FlowTranslationBlock.getallParame, + TBType.pressureTB: PressureTranslationBlock.getallParame, + TBType.tempTB: TemperatureTranslationBlock.getallParame, + TBType.levelTB: LevelTranslationBlock.getallParame, }.get(self.blockType, lambda: []) parmsData = getParmsFunc() @@ -128,18 +162,22 @@ class Block(): # print(parmData) # print(self.startIndex, 3214) parm = Parm(parmData, self.slot, self.startIndex, self) + self.parms.append(parm) + + def getParmsValue(self, callback, callback2): + valueList = [] + # self.loadDataSignal.connect(callback.loadData) + self.thread = LoadDataThread(self) + self.thread.loadDataSignal.connect(callback) + self.thread.start() + self.thread.finished.connect(callback2) + # thread.join() + # print(valueList) + # return valueList def getTBType(self): return - def setTBType(self): - pass - - - - - - if __name__ == '__main__': b = BlockManage(address = 55) diff --git a/model/ProjectModel/ParmManage.py b/model/ProjectModel/ParmManage.py index 83fffe5..f9e1023 100644 --- a/model/ProjectModel/ParmManage.py +++ b/model/ProjectModel/ParmManage.py @@ -32,31 +32,58 @@ class Parm(): def readValue(self): value = self.DPV1Master.readParm(address = self.address, slot = self.slot, index = self.realIndex, length = self.size) if value == '读取错误': - return + return '读取错误' else: - self.analysisValue(value) + return self.analysisValue(value) def analysisValue(self, value): - pass + match self.dataType: + case 'Unsigned8': + return self.unpackU8(value) + case 'Unsigned16': + return self.unpackU16(value) + case 'Unsigned32': + return self.unpackU32(value) + case 'Float': + return self.unpackFloat(value) + case '101': + return self.unpack101(value) + case 'DS-32': + return self.unpackDS32(value) + case 'DS-36': + return self.unpackDS36(value) + case 'DS-37': + return self.unpackDS37(value) + case 'DS-39': + return self.unpackDS39(value) + case 'DS-50': + return self.unpackDS50(value) + case 'OctetString' | 'VisibleString': + return self.unpackStr(value) + case _: + return str(value) def unpackU8(self, value): - return str(struct.unpack('>b', value)) + return str(struct.unpack('>b', value)[0]) def unpackU16(self, value): - return str(struct.unpack('>h', value)) + return str(struct.unpack('>h', value)[0]) + + def unpackU32(self, value): + return str(struct.unpack('>i', value)[0]) def unpackFloat(self, value): - return str(struct.unpack('>f', value)) + return str(round(struct.unpack('>f', value)[0], 4)) def unpackStr(self, value): - return struct.unpack('{}s'.format(str(len(value))), value) + return struct.unpack('{}s'.format(str(len(value))), value)[0] def unpack101(self, value): - valueByte, statusByte = value[:4], value[4] - value = self.unpackFloat(valueByte) - status = self.unpackU8(statusByte) - displayStr = '值:{} 状态:{}'.format(value, status) - return displayStr + valueByte, statusByte = value[:4], value[4].to_bytes(1, byteorder='little') + value = self.unpackFloat(valueByte) + status = self.unpackU8(statusByte) + displayStr = '值:{} 状态:{}'.format(value, status) + return displayStr def unpackDS32(self, value): reserved = self.unpackU8(value[0:1]) @@ -72,54 +99,55 @@ class Parm(): numberOfParameters = self.unpackU16(value[15:17]) addressOfView1 = self.unpackU16(value[17:19]) numberOfViews = self.unpackU8(value[19:20]) - return + return '' def unpackDS36(self, value): - EU100Byte, EU0Byte, unitByte, decPointByte = value[:4], value[4:], value[8:10], value[10] - EU100 = self.unpackFloat(EU100Byte) - EU0 = self.unpackFloat(EU0Byte) - decPoint = self.unpackU8(decPointByte) - unitValue = self.unpackU16(unitByte) - unit = self.unitConver(unitValue) - displayStr = '有效上限:{} 有效下限:{} 单位:{} 小数点:{}'.format(EU100, EU0, unit, decPoint) - return displayStr + EU100Byte, EU0Byte, unitByte, decPointByte = value[:4], value[4:], value[8:10], value[10].to_bytes(1, byteorder='little') + EU100 = self.unpackFloat(EU100Byte) + EU0 = self.unpackFloat(EU0Byte) + decPoint = self.unpackU8(decPointByte) + unitValue = self.unpackU16(unitByte) + unit = self.unitConver(unitValue) + displayStr = '有效上限:{}\r\n有效下限:{}\r\n单位:{}\r\n小数点:{}'.format(EU100, EU0, unit, decPoint) + return displayStr def unpackDS37(self, value): - actualByte, permitByte, normalByte = value[0], value[1], value[2] - actualMode = self.unpackU8(actualByte) - permitMode = self.unpackU8(permitByte) - normalMode = self.unpackU8(normalByte) - displayStr = '实际模式:{} 允许模式:{} 正常模式:{}'.format(actualMode, permitMode, normalMode) - return displayStr + actualByte, permitByte, normalByte = value[0].to_bytes(1, byteorder='little'), value[1].to_bytes(1, byteorder='little'), value[2].to_bytes(1, byteorder='little') + print(type(actualByte), permitByte, normalByte) + actualMode = self.unpackU8(actualByte) + permitMode = self.unpackU8(permitByte) + normalMode = self.unpackU8(normalByte) + displayStr = '实际模式:{}\r\n允许模式:{}\r\n正常模式:{}'.format(actualMode, permitMode, normalMode) + return displayStr def unpackDS39(self, value): - unacknowledgByte, alarmStateByte, timeStampByte, subcodeByte, alarmValueByte = value[0], value[1], value[2:10], value[10:12], value[12:16] - unacknowledg = self.unpackU8(unacknowledgByte) - alarmState = self.unpackU8(alarmStateByte) - subcode = self.unpackU16(subcodeByte) - alarmValue = self.unpackFloat(alarmValueByte) - timestamp = int.from_bytes(timeStampByte, byteorder='big') - timeStr = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(timestamp)) - displayStr = 'Unacknowledged:{} 有无报警{} 时间戳:{} 报警原因:{} 引起报警的值:{}'.format(unacknowledg, alarmState, timeStr, subcode, alarmValue) - return displayStr + unacknowledgByte, alarmStateByte, timeStampByte, subcodeByte, alarmValueByte = value[0].to_bytes(1, byteorder='little'), value[1].to_bytes(1, byteorder='little'), value[2:10], value[10:12], value[12:16] + unacknowledg = self.unpackU8(unacknowledgByte) + alarmState = self.unpackU8(alarmStateByte) + subcode = self.unpackU16(subcodeByte) + alarmValue = self.unpackFloat(alarmValueByte) + timestamp = int.from_bytes(timeStampByte, byteorder='big') + timeStr = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(timestamp)) + displayStr = 'Unacknowledged:{}\r\n有无报警{}\r\n时间戳:{}\r\n报警原因:{}\r\n引起报警的值:{}'.format(unacknowledg, alarmState, timeStr, subcode, alarmValue) + return displayStr def unpackDS50(self, value): - simulateStatusByte, simulateValueByte, simulateEnabledByte = value[0], value[1:5], value[5] - simulateStatus = self.unpackU8(simulateStatusByte) - simulateValue = self.unpackFloat(simulateValueByte) - simulateEnabled = self.unpackU8(simulateEnabledByte) - displayStr = '仿真值状态:{} 仿真值:{} 是否启用仿真:{}' - return displayStr + simulateStatusByte, simulateValueByte, simulateEnabledByte = value[0].to_bytes(1, byteorder='little'), value[1:5], value[5].to_bytes(1, byteorder='little') + simulateStatus = self.unpackU8(simulateStatusByte) + simulateValue = self.unpackFloat(simulateValueByte) + simulateEnabled = self.unpackU8(simulateEnabledByte) + displayStr = '仿真值状态:{}\r\n仿真值:{}\r\n是否启用仿真:{}' + return displayStr def packU8(self, value): - return struct.pack('>b', value) + return struct.pack('>b', value) def packU16(self, value): - return struct.pack('>h', value) + return struct.pack('>h', value) def packFloat(self, value): - return struct.pack('>f', value) + return struct.pack('>f', value) def pack101(self, value, status): valueByte = self.packFloat(value) @@ -143,5 +171,5 @@ class Parm(): return packedData def unitConver(self, unitValue): - unit, desc = '1', '1' - return unit + desc \ No newline at end of file + unit, desc = '1', '1' + return unit + desc \ No newline at end of file diff --git a/protocol/ModBus/DPV1Master.py b/protocol/ModBus/DPV1Master.py index b7f8f83..de52772 100644 --- a/protocol/ModBus/DPV1Master.py +++ b/protocol/ModBus/DPV1Master.py @@ -20,8 +20,7 @@ class SearchSlaveThread(threading.Thread): for address in range(1, 126): if not self.stopEvent.is_set(): self.callback(address, self.master.judgeSlave(address)) - - + def stop(self): self.stopEvent.set() @@ -76,11 +75,17 @@ class DPV1Master(): indexByte = index.to_bytes(1, byteorder='little') readByteStream = b'\x01' + hexAddress + slotByte + indexByte + b'\xF0\x00' searchDate = struct.unpack('>hhh', readByteStream) + self.writeMultipleRegister(1, 750, self.resetData) self.writeMultipleRegister(1, 750, searchDate) time.sleep(0.3) value = self.readHoldingRegisters(1, 750, -(-length // 2)) # -(-length // 2)向上取整 + if value[0] == 57344: + self.writeMultipleRegister(1, 750, self.resetData) + time.sleep(0.1) + return '读取错误' + value = struct.pack('>{}H'.format(len(value)), *value)[:length] + # print(address, slot, index) # print(value) - value = struct.pack('>{}h'.format(len(value)), *value)[:length] self.writeMultipleRegister(1, 750, self.resetData) time.sleep(0.1) if callable(callback):