main
parent d4ab88adf1
commit f6c00407ef

@ -18,7 +18,6 @@ class AreaTabWidget(QMainWindow):
self.areaTabWidget = QTabWidget(self)
self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
# 设置主窗口的中心部分为 QTabWidget
self.setCentralWidget(self.areaTabWidget)
@ -109,6 +108,7 @@ class AreaTabWidget(QMainWindow):
def addAreaWidget(self, widgetList, loacl = True, init = False):
self.mainwindow.readVarTimer.stop()
dataType = widgetList[0].currentText()
# print(widgetList)
order = self.dataTypeTranslate(widgetList[1].currentText())
@ -116,7 +116,7 @@ class AreaTabWidget(QMainWindow):
areaLayout = widgetList[3]
deviceName = self.areaTabWidget.parent().parent().parent().parent().parent().windowTitle()
widgetLists = []
while areaLayout.count():
item = areaLayout.takeAt(0)
widget = item.widget()
@ -126,11 +126,11 @@ class AreaTabWidget(QMainWindow):
if len(byteLineEdit) == 0:
QMessageBox.warning(self, '警告', '请输入字节长度。')
return
else:
widgetList[0].setEnabled(False)
if dataType in ['AI', 'AO']:
areaLabel = QLabel(dataType + str(1) + ": " + byteLineEdit + 'Byte' )
areaLabel = QLabel(dataType + str(1) + ": " + '字节长度: ' + byteLineEdit + ' 当前值: ' )
areaLabel2 =QLabel('0')
if '主站' in deviceName and dataType == 'AI' or ('从站' in deviceName and dataType == 'AO'):
@ -157,14 +157,14 @@ class AreaTabWidget(QMainWindow):
'从站' in deviceName and dataType == 'DO'):
for i in range(int(channelNumber)):
if i % 2 == 0:
areaLabel = QLabel(dataType + str(i + 1) + ": " + byteLineEdit + 'Byte')
areaLabel = QLabel(dataType + str(1) + ": " + '字节长度: ' + byteLineEdit + ' 当前值: ')
areaLabel2 = QLabel('0')
areaLayout.addWidget(areaLabel, i // 2, i % 2)
areaLayout.addWidget(areaLabel2, i // 2, i % 2 + 1)
widgetLists.append([areaLabel2, areaLayout, areaLabel])
else:
areaLabel = QLabel(dataType + str(i + 1) + ": " + byteLineEdit + 'Byte')
areaLabel = QLabel(dataType + str(1) + ": " + '字节长度: ' + byteLineEdit + ' 当前值: ')
areaLabel2 = QLabel('0')
areaLayout.addWidget(areaLabel, i // 2, i % 2 + 2)
areaLayout.addWidget(areaLabel2, i // 2, i % 2 + 3)
@ -174,7 +174,7 @@ class AreaTabWidget(QMainWindow):
'从站' in deviceName and dataType == 'DI'):
for i in range(int(channelNumber)):
if i % 2 == 0:
areaLabel = QLabel(dataType + str(i + 1) + ": " + byteLineEdit + 'Byte')
areaLabel = QLabel(dataType + str(1) + ": " + '字节长度: ' + byteLineEdit + ' 当前值: ')
areaLabel2 = QLabel('0')
areaLineEdit = QLineEdit('0')
editbtn = QPushButton('强制')
@ -186,7 +186,7 @@ class AreaTabWidget(QMainWindow):
editbtn.clicked.connect(lambda checked, btn=editbtn: self.wirteValue(btn))
widgetLists.append([areaLabel2, areaLineEdit, editbtn, areaLabel])
else:
areaLabel = QLabel(dataType + str(i + 1) + ": " + byteLineEdit + 'Byte')
areaLabel = QLabel(dataType + str(1) + ": " + '字节长度: ' + byteLineEdit + ' 当前值: ')
areaLabel2 = QLabel('0')
areaLineEdit = QLineEdit('0')
editbtn = QPushButton('强制')
@ -215,10 +215,12 @@ class AreaTabWidget(QMainWindow):
DevicesManange.updataAreas(dataType, order, byteLineEdit, deviceName, index)
self.mainwindow.devicesManange.getDevice(deviceName).editArea(index = index - 1, type = dataType, order = order, bytes = int(byteLineEdit))
self.mainwindow.devicesManange.recalculateAddress()
self.mainwindow.readVarTimer.start(500)
else:
DevicesManange.addAreas(dataType, order, byteLineEdit, deviceName)
self.mainwindow.devicesManange.getDevice(deviceName).addArea(type = dataType, bytes = int(byteLineEdit), order = order, nums = 1)
self.mainwindow.devicesManange.recalculateAddress()
self.mainwindow.readVarTimer.start(500)
@ -243,8 +245,8 @@ class AreaTabWidget(QMainWindow):
dataType = widgetList[-1].text()[0:2]
# if dataType in ['DI', "DO"]:
didoValueList.append(float(widgetList[1].text()))
valueList.append(didoValueList)
if didoValueList:
valueList.append(didoValueList)
didoValueList = []
# print(valueList)
self.mainwindow.devicesManange.writeAreas(deviceName = deviceName, values = valueList)
@ -252,32 +254,33 @@ class AreaTabWidget(QMainWindow):
def readValue(self):
deviceList = []
areaIdList = []
devices = DevicesManange.getAllDevice()
for device in devices:
deviceName = device[0]
areas = device[3]
if areas is not None:
areas = json.loads(areas)
for area in areas:
areaId = area["id"]
areaIdList.append(areaId)
deviceList.append([deviceName, areaIdList])
index = self.areaTabWidget.currentIndex()
deviceName = self.areaTabWidget.parent().parent().parent().parent().parent().windowTitle()
curIndex = -1
areaIndex = self.areaTabWidget.currentIndex()
if len(self.widgetList) > 0:
widgetLists = self.widgetList[index]
for widgetList in widgetLists:
widgetList[0].setText('AAA')
inputIndex = 0
for index, widgetLists in enumerate(self.widgetList): #获取所有区域的所有的widgetlist
for widgetList in widgetLists:
#获取单个widgetlist
if isinstance(widgetList[1], QLineEdit):
pass
else:
# areaWidgets.append(widgetList)
if areaIndex == index:
curIndex = inputIndex
inputIndex += 1
break
if curIndex == -1:
return
else:
device = self.mainwindow.devicesManange.getDevice(deviceName)
values = device.getAreaValues(curIndex)
areaWidgets = self.widgetList[areaIndex]
for value, widgets in zip(values, areaWidgets):
widgets[0].setText(str(value))
if __name__ == '__main__':
app = QApplication(sys.argv)

@ -37,7 +37,7 @@ class MainWindow(QMainWindow):
self.initUI()
self.initAreaWidget()
self.states = True
def initUI(self):
self.toolbar = QToolBar()
@ -48,7 +48,7 @@ class MainWindow(QMainWindow):
self.addDiviceBtn.setObjectName("addDiviceBtn")
self.addDiviceBtn.triggered.connect(self.createDeciveWidget)
self.startProtocolBtn = QAction("开始通讯", self)
self.startProtocolBtn = QAction("开始读取", self)
self.startProtocolBtn.setObjectName("startProtocolBtn")
self.startProtocolBtn.triggered.connect(self.startProtocol)
@ -68,6 +68,9 @@ class MainWindow(QMainWindow):
self.setWindowTitle("PROFIBUS")
self.setGeometry(1000, 500, 800, 600)
self.readVarTimer = QtCore.QTimer()
self.readVarTimer.timeout.connect(self.readValues)
def deviceWidget(self, windowTitle):
@ -120,8 +123,8 @@ class MainWindow(QMainWindow):
dev = self.devicesManange.getDevice(deviceName = devices[0])
dev.addArea(type = area["type"], order = area["order"], bytes = int(channelBytes), nums = 1)
self.devicesManange.recalculateAddress()
areaTabWidget.initAreaTab(dataType, order, channelBytes)
self.devicesManange.recalculateAddress()
def createDeciveWidget(self):
dialog = DeviceDialog()
@ -130,6 +133,7 @@ class MainWindow(QMainWindow):
windowTitle = deviceName + ' ' + proType + masterSlaveModel + ' ' + pvLowerLimit + '-' + pvUpperLimit + pvUnit
DeviceDB().addDevice(deviceName = windowTitle, proType = proType, masterSlaveModel = masterSlaveModel, pvUpperLimit=pvUpperLimit, pvLowerLimit=pvLowerLimit, pvUnit=pvUnit)
self.devicesManange.addDevice(proType = proType, masterSlaveModel = masterSlaveModel, deviceName = windowTitle)
self.devicesManange.recalculateAddress()
else:
return
@ -137,7 +141,19 @@ class MainWindow(QMainWindow):
def startProtocol(self):
if self.states == True:
self.readVarTimer.start(500)
self.states = False
self.startProtocolBtn.setText('停止读取')
else:
self.readVarTimer.stop()
self.states = True
self.startProtocolBtn.setText('开始读取')
def readValues(self):
# try:
self.devicesManange.readAreas()
# except Exception as e:
# print(e)
for subWindow in self.subWindows:
areaTabWidget = subWindow.widget().widget().centralWidget()
areaTabWidget.readValue()

@ -10,16 +10,18 @@ import struct
#从站 "AI" "DI"可强制
#主站 "AO" "DO"可强制
class Device():
inputStartAddress = None
inputEndAddress = None
outputStartAddress = None
outputEndAddress = None
inputStartAddress = 0
inputEndAddress = 0
outputStartAddress = 0
outputEndAddress = 0
protocolType = None
masterOrSlave = None
deviceName = None
def __init__(self):
self.inputAreas = []
self.outputAreas = []
self.indexDict = collections.OrderedDict()
# 有序字典 键:总区域索引 值: [类型(输入 : 0, 或输出 : 1), 该类型的第几个区域索引]
def addArea(self, type, nums, bytes, order = 'ABCD'):
area = Area()
@ -29,32 +31,34 @@ class Device():
area.bytes = bytes
area.length = self.getLength(nums, bytes)
area.nums = nums
area.currentValue = [0] * nums
if type in ["AI", "DI"]:
area.startAddress = 0 if not self.inputEndAddress else self.inputEndAddress + 1
area.endAddress = area.startAddress + area.length
self.inputEndAddress = area.endAddress
area.addressList = np.arange(area.startAddress, area.endAddress + 1, area.bytes).tolist()
self.indexDict[len(self.indexDict.values())] = len(self.inputAreas)
self.inputAreas.append(area)
elif type in ["DO" , "AO"]:
area.startAddress = 0 if not self.outputEndAddress else self.outputEndAddress + 1
area.endAddress = area.startAddress + area.length
self.outputEndAddress = area.endAddress
area.addressList = np.arange(area.startAddress, area.endAddress + 1, area.bytes).tolist()
self.indexDict[len(self.indexDict.values())] = len(self.outputAreas)
self.outputAreas.append(area)
# print(self.inputAreas)
# print(id(self), self.outputAreas)
# print(area.addressList, area.startAddress, area.endAddress, self.outputAreas)
def delArea(self, index, type):
if type in ["DI", "AI"]:
self.inputAreas.pop(index)
self.inputAreas.pop(self.indexDict[index])
elif type in ["AO", "DO"]:
self.outputAreas.pop(index)
self.outputAreas.pop(self.indexDict[index])
# self.recalculateAddress()
def recalculateAddress(self):
endAddress = 0
for inputOrOutput, areas in enumerate([self.inputAreas, self.outputAreas]):
endAddress = 0
for index, area in enumerate(areas):
if index == 0 and inputOrOutput == 0:
area.startAddress = self.inputStartAddress
@ -64,37 +68,37 @@ class Device():
area.startAddress = areas[index - 1].endAddress + 1
area.endAddress = area.startAddress + area.length
area.addressList = np.arange(area.startAddress, area.endAddress + 1, area.bytes).tolist()
print(area.addressList, area.startAddress, area.endAddress, self.deviceName)
endAddress = area.endAddress
else:
if inputOrOutput == 0:
self.inputEndAddress = endAddress
elif inputOrOutput == 1:
self.outputEndAddress = endAddress
endAddress = 0
# endAddress = 0
# print(self.deviceName, self.inputEndAddress)
def editArea(self, index, type, order, bytes):
if type in ["DI", "AI"]:
self.inputAreas[index].type = type
self.inputAreas[index].order = order
self.inputAreas[index].bytes = bytes
self.inputAreas[self.indexDict[index]].order = order
self.inputAreas[self.indexDict[index]].bytes = bytes
elif type in ["AO", "DO"]:
self.outputAreas[index].type = type
self.outputAreas[index].order = order
self.outputAreas[index].bytes = bytes
self.outputAreas[self.indexDict[index]].order = order
self.outputAreas[self.indexDict[index]].bytes = bytes
# self.recalculateAddress()
def getAreaValues(self, index):
if self.masterOrSlave == "主站"
if self.masterOrSlave == "从站":
return self.outputAreas[index].currentValue
else:
# print(self.inputAreas, index)
return self.inputAreas[index].currentValue
def getLength(self, nums, bytes):
length = int(nums) * int(bytes)
# length = length / 2
return length - 1
return length
@ -176,9 +180,18 @@ class DevicesManange():
def recalculateAddress(self):
for devicesDict in [self.paMasterDevices, self.paSlaveDevices, self.dpMasterDevices, self.dpSlaveDevices]:
# print(len(devicesDict))
for index, (deviceName, device) in enumerate(devicesDict.items()):
device.inputStartAddress = 0 if index == 0 else list(devicesDict.values())[index - 1].inputEndAddress + 1
device.outputStartAddress = 0 if index == 0 else list(devicesDict.values())[index - 1].outputEndAddress + 1
if index == 0:
device.inputStartAddress = 0
device.outputStartAddress = 0
else:
inputAddress = list(devicesDict.values())[index - 1].inputEndAddress
outputAddress = list(devicesDict.values())[index - 1].outputEndAddress
device.inputStartAddress = 0 if inputAddress == 0 else inputAddress + 1
device.outputStartAddress = 0 if outputAddress == 0 else outputAddress + 1
# print(device.inputStartAddress, device.inputEndAddress, deviceName, '输入')
# print(device.outputStartAddress, device.outputEndAddress, deviceName, 'shuchu')
device.recalculateAddress()
# previousDevice = device
@ -189,8 +202,10 @@ class DevicesManange():
return devicesDict[deviceName]
def writeAreas(self, deviceName, values):
# print(values)
bytes = b""
device = self.getDevice(deviceName)
# print(device, deviceName)
if device.type == "DP" and device.masterOrSlave == "主站":
curProDict = self.dpMasterDevices
areas = device.outputAreas
@ -207,58 +222,73 @@ class DevicesManange():
areas = device.inputAreas
curProDict = self.paSlaveDevices
modbusM = self.paSlaveModbus
# print(values)
for area, value in zip(areas, values):
area.forceValue = value
if area.type in ['DI', 'DO']:
area.forceValue = value[8:] + value[:8]
for device in curProDict.values():
forceAreas = device.outputAreas if device.masterOrSlave == "主站" else device.inputAreas
for area in forceAreas:
# print(area.type)
# print(area.forceValue)
if area.type in ["AI", "AO"]:
byte = floatToBytes(area.forceValue, area.bytes, order = area.order)
elif area.type in ["DI", "DO"]:
if device.type == "PA" and device.masterOrSlave == "从站" and len(area.forceValue) == 16:
area.forceValue = area.forceValue[8:] + area.forceValue[:8]
# if device.type == "PA" and device.masterOrSlave == "从站" and len(area.forceValue) == 16:
byte = coilsToBytes([int(x) for x in area.forceValue], area.bytes)
bytes += byte
else:
if len(bytes) % 2 != 0:
bytes += struct.pack('B', 0)
# print(bytes)
values = struct.unpack('!' + 'H' * int(len(bytes) / 2), bytes)
modbusM.writeMultipleRegister(slaveId = 1, address = 0, outputValue = values)
# print(struct.unpack('>f', struct.pack('!HH', *values[:2])))
def readAreas(self):
for index, curProDict enumerate(devicesDict) in [self.paMasterDevices, self.paSlaveDevices, self.dpMasterDevices, self.dpSlaveDevices]:
for index, curProDict in enumerate([self.paMasterDevices, self.paSlaveDevices, self.dpMasterDevices, self.dpSlaveDevices]):
match index:
case 0:
areaType = 'output'
areaType = 'input'
modbusM = self.paMasterModbus
case 1:
areaType = 'input'
modbusM = self.paSlaverModbus
case 2:
areaType = 'output'
modbusM = self.paSlaveModbus
case 2:
areaType = 'input'
modbusM = self.dpMasterModbus
case 3:
areaType = 'input'
modbusM = self.dpSlaverModbus
lastDevice = list(curProDict.values())[-1]
bytesNums = lastDevice.inputEndAddress if areaType == 'input' else lastDevice.outputEndAddress
areaType = 'output'
modbusM = self.dpSlaveModbus
if len(list(curProDict.values())) == 0:
continue
inputEndAddress = max([x.inputEndAddress for x in list(curProDict.values())])
outputEndAddress = max([x.outputEndAddress for x in list(curProDict.values())])
bytesNums = inputEndAddress if areaType == 'input' else outputEndAddress
intNums = int(bytesNums / 2) if bytesNums % 2 == 0 else int(bytesNums / 2) + 1
intValues = modbusM.readHoldingRegisters(slaveId = 1, startAddress = 0, intNums)
bytesValues = struct.pack(f"!{'H' * len(intValues)}")
if bytesNums == 0:
continue
intValues = modbusM.readHoldingRegisters(slaveId = 1, startAddress = 0, varNums = intNums)
bytesValues = struct.pack(f"!{'H' * len(intValues)}", *intValues)
for device in curProDict.values():
readAreas = device.inputAreas if areaType == 'input' else device.outputAreas
for area in readAreas:
bytes = bytesValues[area.startAddress, area.endAddress + 1]
if area.startAddress == 0:
bytes = bytesValues[area.startAddress:area.endAddress]
else:
bytes = bytesValues[area.startAddress - 1:area.endAddress]
if area.type in ['AI', 'AO']:
for i in range(0, len(bytes), 4):
byte = byte[i:i+4]
byte = bytes[i:i+4]
if len(byte) != 4:
return
area.currentValue[i] = struct.unpack('!f', reorderBytes(byte))
continue
area.currentValue[i] = round(struct.unpack('!f', reorderBytes(byte, area.order))[0], 4)
elif area.type in ['DI', 'DO']:
area.currentValue = bytesToCoils(byte)
bytes = bytes[::-1]
area.currentValue = bytesToCoils(bytes)
# print(area.currentValue)
@classmethod
def addAreas(self, type, order, bytes, deviceName):
if DeviceDB.getByName(deviceName=deviceName).areaJson is None:

@ -91,6 +91,7 @@ def coilsToBytes(values, length):
def bytesToCoils(valueByte):
binaryNumber = ''.join([format(x, '08b') for x in valueByte])
values = list(reversed([int(x) for x in binaryNumber]))
# print(values)
return values

Loading…
Cancel
Save