diff --git a/.gitignore b/.gitignore index e69de29..085c4fe 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1,2 @@ +*.pyc +*.db diff --git a/UI/AreaTabWidget.py b/UI/AreaTabWidget.py index e5a173d..9171781 100644 --- a/UI/AreaTabWidget.py +++ b/UI/AreaTabWidget.py @@ -8,9 +8,10 @@ from model.ProjectModel.DeviceManage import DevicesManange, Device class AreaTabWidget(QMainWindow): - def __init__(self): + def __init__(self, mainwindow): super().__init__() self.initUI() + self.mainwindow = mainwindow def initUI(self): # 创建一个 QTabWidget self.widgetList = [] @@ -27,7 +28,7 @@ class AreaTabWidget(QMainWindow): widgetList[1].setCurrentIndex(order) widgetList[2].setText(channelBytes) - self.addAreaWidget(widgetList, loacl = False) + self.addAreaWidget(widgetList, loacl = False, init = True) def addAreaTab(self): @@ -91,10 +92,12 @@ class AreaTabWidget(QMainWindow): self.areaTabWidget.removeTab(index) del self.widgetList[index] Device.delAreas(deviceName, index) + self.mainwindow.devicesManange.getDevice(deviceName).delArea(index) + self.mainwindow.devicesManange.recalculateAddress() - def addAreaWidget(self, widgetList, loacl = True): + def addAreaWidget(self, widgetList, loacl = True, init = False): dataType = widgetList[0].currentText() order = self.dataTypeTranslate(widgetList[1].currentText()) byteLineEdit = widgetList[2].text() @@ -190,9 +193,15 @@ class AreaTabWidget(QMainWindow): if loacl: print(index) del self.widgetList[index - 1] + if init: + return 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() else: DevicesManange.addAreas(dataType, order, byteLineEdit, deviceName) + self.mainwindow.devicesManange.getDevice(deviceName).addArea(type = dataType, bytes = int(byteLineEdit), nums = 1) + self.mainwindow.devicesManange.recalculateAddress() diff --git a/UI/MainWindow.py b/UI/MainWindow.py index 37419f7..74d0faf 100644 --- a/UI/MainWindow.py +++ b/UI/MainWindow.py @@ -16,6 +16,9 @@ from utils.DBModels.BaseModel import * from UI.AreaTabWidget import AreaTabWidget from utils.DBModels.DeviceModels import DeviceDB from model.ClientModel.Client import Client +from model.ProjectModel.DeviceManage import DevicesManange + + class CommonHelper: def __init__(self): pass @@ -29,10 +32,11 @@ class CommonHelper: class MainWindow(QMainWindow): def __init__(self): super().__init__() + self.devicesManange = DevicesManange() self.subWindows = [] #存储设备widget self.initUI() self.initAreaWidget() - self.projectManage = DevicesManange() + def initUI(self): @@ -69,7 +73,7 @@ class MainWindow(QMainWindow): def deviceWidget(self, windowTitle): subWindow = AreaQMdiSubWindow(self)# 创建一个子窗口 subWindow.setObjectName('subWindow') - areaTabWidget = AreaTabWidget() + areaTabWidget = AreaTabWidget(self) #新建mainWindows放入subwindows areaMainWindow = QMainWindow() @@ -104,16 +108,17 @@ class MainWindow(QMainWindow): def initAreaWidget(self): alldevices = DevicesManange.getAllDevice() - for devices in alldevices: areas = devices[3] + self.devicesManange.addDevice(proType = devices[1], masterSlaveModel = devices[2], deviceName = devices[0]) areaTabWidget = self.deviceWidget(devices[0]).widget().widget().centralWidget() if areas is not None: areas = json.loads(areas) for area in areas: dataType, order = self.tran(area["type"], area["order"]) channelBytes = area["bytes"] - + self.devicesManange.getDevice(deviceName = devices[0]).addArea(type = area["type"], order = order, bytes = int(channelBytes), nums = 1) + self.devicesManange.recalculateAddress() areaTabWidget.initAreaTab(dataType, order, channelBytes) def createDeciveWidget(self): @@ -122,6 +127,7 @@ class MainWindow(QMainWindow): deviceName, proType, masterSlaveModel, pvUpperLimit, pvLowerLimit, pvUnit = dialog.getParameters() 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) else: return @@ -164,6 +170,7 @@ class AreaQMdiSubWindow(QMdiSubWindow): def closeEvent(self, event): self.parentWindow.subWindows.remove(self) DeviceDB.deleteDevice(deviceName = self.windowTitle()) + self.parentWindow.devicesManange.delDevice(deviceName = self.windowTitle()) diff --git a/model/ProjectModel/AreaManage.py b/model/ProjectModel/AreaManage.py index 8bb3528..f5fe4a1 100644 --- a/model/ProjectModel/AreaManage.py +++ b/model/ProjectModel/AreaManage.py @@ -3,27 +3,13 @@ import json import collections import time -from PyQt5.QtWidgets import QApplication, QMainWindow, QToolBar, QMdiArea, QAction, QInputDialog, QDialog, QFormLayout, QLineEdit, \ - QMdiSubWindow, QDialogButtonBox, QWidget, QComboBox, QTabBar, QTabWidget, QGridLayout, QLabel, QPushButton, QSpacerItem, QSizePolicy, QHBoxLayout, QTableWidget -from model.ProjectModel.DeviceManage import DevicesManange from protocol.ModBus.TCPMaster import TcpMaster from utils.DBModels.DeviceModels import DeviceDB # from utils.DBModels.ClientModels import DeviceDB -jsonCon = json.dumps([{ - "id": 0, - "type": "AO", - "nums": 4, - "bytes": 2, -}, - { - "id": 1, - "type": "AI", - "nums": 8, - "bytes": 4, - }]) + class Area(): @@ -32,77 +18,16 @@ class Area(): bytes = None type = None addressList = [] - valueType = 'ABCD' + order = 'ABCD' def __init__(self): pass - def writeValues(self): - self.masterWriteValues = TcpMaster('127.0.0.2', 502) - self.slaveWriteValues = TcpMaster('127.0.0.1', 502) - print(self.masterValues,'sssssss') - self.masterWriteValues.writeSingleRegister(1, 0, self.masterValues) - self.slaveWriteValues.writeSingleRegister(1, 0, self.slaveRealtimeValue) - - - - - - - - -class Devices(): - areas = [] - startAddress = None - endAddress = None - - - def __init__(self, jsonCon=[]): - for areaJson in jsonCon: - self.areas.append(Area(areaJson)) - - def addAreas(self, type, nums, bytes, deviceName): - if DeviceDB.getByName(deviceName=deviceName).areaJson is None: - jsonCon = ([{ - "id": 1, - "type": type, - "nums": nums, - "bytes": bytes, - - }]) - else: - jsonCon = json.loads(DeviceDB.getByName(deviceName=deviceName).areaJson) - id = jsonCon[-1]["id"] + 1 - jsonCon.append({ - "id": id, - "type": type, - "nums": nums, - "bytes": bytes, - - }) - areaJson = json.dumps(jsonCon) - DeviceDB.update(areaJson=areaJson).where(DeviceDB.deviceName == deviceName).execute() - - def getAllDevice(self): - # 查询所有设备 - devices = DeviceDB.get_all() - if devices is 'error': - return - l = [] - for x in devices: - l.append([x.deviceName, x.proType, x.masterSlaveModel, x.areaJson]) - return l - - def writeAreas(self): - pass - - - diff --git a/model/ProjectModel/DeviceManage.py b/model/ProjectModel/DeviceManage.py index 469cde1..1b2e121 100644 --- a/model/ProjectModel/DeviceManage.py +++ b/model/ProjectModel/DeviceManage.py @@ -1,56 +1,90 @@ import collections import json from utils.DBModels.DeviceModels import DeviceDB - +from model.ProjectModel.AreaManage import Area +import numpy as np class Device(): - areas = [] - startAddress = 0 - endAddress = 0 + inputAreas = [] + outputAreas = [] + inputStartAddress = None + inputEndAddress = None + outputStartAddress = None + outputEndAddress = None protocolType = None masterOrSlave = None deviceName = None def __init__(self): pass - # def addArea(self, type, nums, bytes): - # area = Area() - # area.type = type - # area.startAddress = 0 if not self.startAddress else: self.endAddress + 1 - # area.length = self.getLength(nums, bytes) - # area.endAddress = startAddress + length - # self.endAddress = area.endAddress - # area.addressList = list(range(area.startAddress, area.endAddress + 1, bytes)) - # areas.append(area) - - def delArea(self, index): - self.areas.pop(index) - self.recalculateAddress() - - def recalculateAddress(self): - for index, area in enumerate(self.areas): - area.startAddress = self.startAddress + def addArea(self, type, nums, bytes, order = 'ABCD'): + area = Area() + bytes = int(bytes) + area.type = type + area.order = order + area.bytes = bytes + area.length = self.getLength(nums, bytes) + if type in ["AI", "DI"]: + area.startAddress = 0 if not self.inputEndAddress else self.inputEndAddress + 1 area.endAddress = area.startAddress + area.length - area.addressList = list(range(area.startAddress, area.endAddress + 1, area.bytes)) - else: - self.endAddress = area.endAddress + self.inputEndAddress = area.endAddress + area.addressList = np.arange(area.startAddress, area.endAddress + 1, area.bytes).tolist() + 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.outputAreas.append(area) + print(area.addressList, area.startAddress, self.inputEndAddress) + + def delArea(self, index, type): + if type in ["DI", "AI"]: + self.inputAreas.pop(index) + elif type in ["AO", "DO"]: + self.outputAreas.pop(index) + # self.recalculateAddress() - def editAreaType(self, index, type): - self.areas[index].type = type + def recalculateAddress(self): + endAddress = 0 + for inputOrOutput, areas in enumerate([self.inputAreas, self.outputAreas]): + for index, area in enumerate(areas): + if index == 0 and inputOrOutput == 0: + area.startAddress = self.inputStartAddress + elif index == 0 and inputOrOutput == 1: + area.startAddress = self.outputStartAddress + else: + area.startAddress = areas[index - 1].endAddress + area.endAddress = area.startAddress + area.length + area.addressList = np.arange(area.startAddress, area.endAddress + 1, area.bytes).tolist() + endAddress = area.endAddress + else: + if inputOrOutput == 0: + self.inputEndAddress = endAddress + elif inputOrOutput == 1: + self.outputEndAddress = endAddress + + + 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 + elif type in ["AO", "DO"]: + self.outputAreas[index].type = type + self.outputAreas[index].order = order + self.outputAreas[index].bytes = bytes + # self.recalculateAddress() - def editAreaValueType(self, index, varType): - self.areas[index].valueType = varType def getArea(self, index): return self.areas[index] def getLength(self, nums, bytes): length = int(nums) * int(bytes) - if length % 2 != 0: - length = (length + 1) // 2 - else: - length = length / 2 + length = length / 2 + return length @@ -111,26 +145,28 @@ class DevicesManange(): curProDict = self.paSlaveDevices if len(curProDict) == 0: - device.startAddress = 0 + device.inputStartAddress = 0 + device.outputStartAddress = 0 else: - device.startAddress = curProDict.values[-1].endAddress + 1 + device.inputStartAddress = curProDict.values[-1].inputEndAddress + 1 + device.outputStartAddress = curProDict.values[-1].outputEndAddress + 1 curProDict[deviceName] = device def initDevices(self): pass - def delDevice(self): + def delDevice(self, deviceName): for devicesDict in [self.paMasterDevices, self.paSlaveDevices, self.dpMasterDevices, self.dpSlaveDevices]: if deviceName in devicesDict: - del deviceDict[deviceName] + del devicesDict[deviceName] self.recalculateAddress() - # def recalculateAddress(self, deviceDict): - # for devicesDict in [self.paMasterDevices, self.paSlaveDevices, self.dpMasterDevices, self.dpSlaveDevices]: - # for index, (deviceName, device) in enumerate(ordered_dict.items()): - # device.startAddress = 0 in index = 0 else: device = previousDevice.endAddress + 1 - # device.recalculateAddress() - # previousDevice = device + def recalculateAddress(self): + for devicesDict in [self.paMasterDevices, self.paSlaveDevices, self.dpMasterDevices, self.dpSlaveDevices]: + for index, (deviceName, device) in enumerate(devicesDict.items()): + device.startAddress = 0 if index == 0 else previousDevice.endAddress + 1 + device.recalculateAddress() + previousDevice = device def getDevice(self, deviceName): @@ -211,4 +247,5 @@ class DevicesManange(): l = [] for x in devices: l.append([x.deviceName, x.proType, x.masterSlaveModel, x.areaJson]) - return l \ No newline at end of file + return l + diff --git a/protocol/ModBus/TCPMaster.py b/protocol/ModBus/TCPMaster.py index dbcbbd5..291b95a 100644 --- a/protocol/ModBus/TCPMaster.py +++ b/protocol/ModBus/TCPMaster.py @@ -18,7 +18,7 @@ class TcpMaster(): # hooks.install_hook("modbus_tcp.TcpMaster.after_recv", afterRecv) # hooks.install_hook("modbus_tcp.TcpMaster.after_send", afterSend) - def writeSingleRegister(self, slaveId, address, outputValue, order = 'ABCD'): + def writeMultipleRegister(self, slaveId, address, outputValue, order = 'ABCD'): try: valueByte = [] for i in outputValue: @@ -44,18 +44,18 @@ class TcpMaster(): def readHoldingRegisters(self, slaveId, startAddress, varNums, order = 'ABCD'): try: if order == 'int': - valueByte = self.master.execute(slaveId, cst.READ_HOLDING_REGISTERS, startAddress, varNums)[0] + value = self.master.execute(slaveId, cst.READ_HOLDING_REGISTERS, startAddress, varNums)[0] else: - value = self.master.execute(slaveId, cst.READ_HOLDING_REGISTERS, startAddress, 2) - if order == 'ABCD': # 大端模式 - valueByte = ABCDToFloat(value) - elif order == 'DCBA': # 小端模式 - valueByte = DCBAToFloat(value) - elif order == 'BADC': - valueByte = BADCToFloat(value) - elif order == 'CDAB': - valueByte = CDABToFloat(value) - return valueByte + value = self.master.execute(slaveId, cst.READ_HOLDING_REGISTERS, startAddress, varNums) + # if order == 'ABCD': # 大端模式 + # valueByte = ABCDToFloat(value) + # elif order == 'DCBA': # 小端模式 + # valueByte = DCBAToFloat(value) + # elif order == 'BADC': + # valueByte = BADCToFloat(value) + # elif order == 'CDAB': + # valueByte = CDABToFloat(value) + return value except: return 'error'