commit 4c8045360640054873871a59729895578bdb1c5a Author: zhangxuxutm <951937200@qq.com> Date: Sat Sep 2 20:38:25 2023 +0800 0902 diff --git a/UI/AreaSettingWidget.py b/UI/AreaSettingWidget.py new file mode 100644 index 0000000..52463de --- /dev/null +++ b/UI/AreaSettingWidget.py @@ -0,0 +1,48 @@ +from PyQt5.QtWidgets import QDialog, QFormLayout, QLineEdit, QComboBox, QDialogButtonBox, QApplication + +import sys + +class AreaSettingWidget(QDialog): + def __init__(self, parent=None): + super().__init__(parent) + self.initUI() + def initUI(self): + layout = QFormLayout() + varType = QComboBox() + varType.addItems(['AI', 'AO', 'DI', 'DO']) + varType.setObjectName('varType') + + channelNums = QLineEdit() + channelNums.setObjectName('channelNums') + + channelBytes = QLineEdit() + channelBytes.setObjectName('channelBytes') + + + + layout.addRow('协议类型:', varType) + layout.addRow('通道数:', channelNums) + layout.addRow("字节长度:", channelBytes) + + + button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) + button_box.accepted.connect(self.accept) + button_box.rejected.connect(self.reject) + + layout.addRow(button_box) + + self.setLayout(layout) + self.setWindowTitle("通道配置") + + def getParameters(self): + varType = self.findChild(QComboBox, "varType").currentText() + channelNums = self.findChild(QLineEdit, "channelNums").text() + channelBytes = self.findChild(QLineEdit, "channelBytes").text() + + return varType, channelNums, channelBytes + +if __name__ == '__main__': + app = QApplication(sys.argv) + window = AreaSettingWidget() + window.show() + sys.exit(app.exec_()) \ No newline at end of file diff --git a/UI/AreaWidget.py b/UI/AreaWidget.py new file mode 100644 index 0000000..4cf7678 --- /dev/null +++ b/UI/AreaWidget.py @@ -0,0 +1,61 @@ +from PyQt5.QtWidgets import QApplication, QMainWindow, QToolBar, QMdiArea, QAction, QInputDialog, QDialog, QFormLayout, QLineEdit, \ + QMdiSubWindow, QDialogButtonBox, QWidget, QComboBox, QTabBar, QTabWidget, QGridLayout, QLabel, QPushButton, QSpacerItem,QSizePolicy +from AreaSettingWidget import AreaSettingWidget + +import sys + +class AreaWidget(QWidget): + def __init__(self): + super().__init__() + self.initUI() + + def initUI(self): + + self.sub_window = QMdiSubWindow() # 创建一个子窗口 + self.layoutAI = QGridLayout() + + self.widget = QWidget() + self.widget.setLayout(self.layoutAI) + + self.newbtn = QPushButton('New') + self.delbtn = QPushButton('Del') + self.layoutAI.addWidget(self.newbtn, 0, 0) + self.layoutAI.addWidget(self.delbtn, 0, 1) + self.newbtn.clicked.connect(lambda: self.newArea) + self.delbtn.clicked.connect(self.delArea) + + + self.layoutAI.addWidget(self.newbtn, 0, 0, 1, 1) + + + self.layoutAI.addWidget(self.delbtn, 0, 2, 1, 1) + + self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) + + self.layoutAI.addItem(self.horizontalSpacer, 0, 1, 1, 1) + + self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) + + self.layoutAI.addItem(self.verticalSpacer, 1, 0, 1, 1) + + # self.sub_window.setGeometry(100, 100, 400, 300) + self.sub_window.setWidget(self.widget) + + def newArea(self): + print(1) + areaSettingWidget = AreaSettingWidget() + if areaSettingWidget.exec_() == QDialog.Accepted: + deviceName, proType, varType = areaSettingWidget.getParameters() + + + + def delArea(self): + pass + + +if __name__ == '__main__': + app = QApplication(sys.argv) + window = AreaWidget() + window.show() + sys.exit(app.exec_()) + diff --git a/UI/DeviceWidget.py b/UI/DeviceWidget.py new file mode 100644 index 0000000..aa7b4a8 --- /dev/null +++ b/UI/DeviceWidget.py @@ -0,0 +1,55 @@ +from PyQt5.QtWidgets import QDialog, QFormLayout, QLineEdit, QComboBox, QDialogButtonBox + +import sys + +class DeviceDialog(QDialog): + def __init__(self, parent=None): + super().__init__(parent) + self.initUI() + + def initUI(self): + layout = QFormLayout() + proType = QComboBox() + proType.addItems(['DP', 'PA']) + proType.setObjectName('ProtocolType') + masterSlaveModel = QComboBox() + masterSlaveModel.addItems(['主站', '从站']) + masterSlaveModel.setObjectName('masterSlaveModel') + + deviceName = QLineEdit() + deviceName.setObjectName('deviceName') + + pvUpperLimit = QLineEdit() + pvUpperLimit.setObjectName('pvUpperLimit') + + pvLowerLimit = QLineEdit() + pvLowerLimit.setObjectName('pvLowerLimit') + + pvUnit = QLineEdit() + pvUnit.setObjectName('pvUnit') + + layout.addRow('协议类型', proType) + layout.addRow('主从模式', masterSlaveModel) + layout.addRow("设备名:", deviceName) + layout.addRow("量程上限:", pvUpperLimit) + layout.addRow("量程下限:", pvLowerLimit) + layout.addRow("单位:", pvUnit) + + + button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) + button_box.accepted.connect(self.accept) + button_box.rejected.connect(self.reject) + + layout.addRow(button_box) + + self.setLayout(layout) + self.setWindowTitle("Input Parameters") + + def getParameters(self): + proType = self.findChild(QComboBox, "ProtocolType").currentText() + masterSlaveModel = self.findChild(QComboBox, "masterSlaveModel").currentText() + deviceName = self.findChild(QLineEdit, "deviceName").text() + pvUpperLimit = self.findChild(QLineEdit, "pvUpperLimit").text() + pvLowerLimit = self.findChild(QLineEdit, "pvLowerLimit").text() + pvUnit = self.findChild(QLineEdit, "pvUnit").text() + return deviceName, proType, masterSlaveModel, pvUpperLimit, pvLowerLimit, pvUnit \ No newline at end of file diff --git a/UI/MainWindow.py b/UI/MainWindow.py new file mode 100644 index 0000000..b449f6d --- /dev/null +++ b/UI/MainWindow.py @@ -0,0 +1,270 @@ +import sys +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, QScrollArea +from PyQt5 import QtCore +from DeviceWidget import * +from AreaWidget import AreaWidget +from UI.AreaSettingWidget import AreaSettingWidget +from model.ProjectModel.AreaManage import Devices, DevicesManange, Area +from protocol.ModBus.ModBusThread import MyThread +from utils.DBModels.BaseModel import * +from utils.DBModels.ClientModels import DeviceDB +from model.ClientModel.Client import Client + + +class MainWindow(QMainWindow): + def __init__(self): + super().__init__() + self.initUI() + self.area = Area() + self.number = 0 + self.labelText = [] + self.lineEditText = [] + self.devicesmanage = DevicesManange() + self.sub_windows = [] + self.initAreaWidget() + self.getTextValue() + + def initUI(self): + self.toolbar = QToolBar() + + self.addToolBar(self.toolbar) + # self.setWindowState(self.windowState() | QtCore.Qt.WindowMaximized) + self.action1 = QAction("添加设备", self) + self.action1.triggered.connect(self.createDeciveWidget) + self.action2 = QAction("开始通讯", self) + self.action2.triggered.connect(self.startProtocol) + + self.toolbar.addAction(self.action1) + self.toolbar.addAction(self.action2) + + self.mdi_area = QMdiArea() + # self.scrollArea = QScrollArea() + # self.scrollArea.setWidget(self.mdi_area) + + self.setCentralWidget(self.mdi_area) + + + # self.mdi_area.setViewMode(QMdiArea.TabbedView) + # self.mdi_area.setTabsClosable(False) + # self.mdi_area.setTabsMovable(True) + + + self.setWindowTitle("Main Window") + self.setGeometry(1000, 500, 800, 600) + + def initAreaWidget(self): + alldevices = Devices().getAllDevice() + + for devices in alldevices: + layout = self.deviceWidget(devices[0]).widget().widget().layout().itemAt(1).widget().layout() + areas = devices[3] + number = 0 + masterSlaveModel = devices[2] + if areas is not None: + areas = json.loads(areas) + for area in areas: + varType = area["type"] + channelNums = area["nums"] + channelBytes = area["bytes"] + for i in range(int(channelNums)): + if masterSlaveModel == '主站': + if (i + number) % 2 == 0: + layout.addWidget(QLabel(varType + str(i + 1) + ": " + channelBytes + 'Byte'), (i + number) // 2, + (i + number) % 2) + layout.addWidget(QLabel('0'), (i + number) // 2, (i + number) % 2 + 1) + layout.addWidget(QLineEdit('0'), (i + number) // 2, (i + number) % 2 + 2) + + else: + layout.addWidget(QLabel(varType + str(i + 1) + ": " + channelBytes + 'Byte'), (i + number) // 2, + (i + number) % 2 + 3) + layout.addWidget(QLabel('0'), (i + number) // 2, (i + number) % 2 + 4) + layout.addWidget(QLineEdit('0'), (i + number) // 2, (i + number) % 2 + 5) + else: + if (i + number) % 2 == 0: + layout.addWidget(QLabel(varType + str(i + 1) + ": " + channelBytes + 'Byte'), (i + number) // 2, + (i + number) % 2) + layout.addWidget(QLabel('0'), (i + number) // 2, (i + number) % 2 + 1) + layout.addWidget(QLineEdit('0'), (i + number) // 2, (i + number) % 2 + 2) + else: + layout.addWidget(QLabel(varType + str(i + 1) + ": " + channelBytes + 'Byte'), (i + number) // 2, + (i + number) % 2 + 3) + layout.addWidget(QLabel('0'), (i + number) // 2, (i + number) % 2 + 4) + layout.addWidget(QLineEdit('0'), (i + number) // 2, (i + number) % 2 + 5) + + number = number + int(channelNums) + + + def deviceWidget(self, windowTitle): + sub_window = AreaQMdiSubWindow() # 创建一个子窗口 + areaLayout1 = QGridLayout() + areaLayout2 = QGridLayout() + + horizontalLayout = QHBoxLayout() + horizontalLayout.setObjectName("horizontalLayout") + + # tableWidget = QTableWidget() + + widget = QWidget() + widget.setLayout(areaLayout1) + + widgetArea = QWidget() + widgetArea.setLayout(areaLayout2) + + newbtn = QPushButton('New') + editbtn = QPushButton('修改') + delbth = QPushButton('删除') + + self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) + self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) + + horizontalLayout.addWidget(newbtn) + horizontalLayout.addItem(self.horizontalSpacer) + horizontalLayout.addWidget(editbtn) + horizontalLayout.addWidget(delbth) + + newbtn.clicked.connect(lambda: self.newAreaWidget(sub_window)) + editbtn.clicked.connect(self.editAreaWidget) + delbth.clicked.connect(self.deleteAreaWidget) + + areaLayout1.addLayout(horizontalLayout, 0, 0, 1, 1) + areaLayout1.addWidget(widgetArea, 1, 0, 1, 1) + areaLayout1.addItem(self.verticalSpacer) + + scroll_widget = QScrollArea() + scroll_widget.setWidgetResizable(True) + scroll_widget.setWidget(widget) + + sub_window.setWindowTitle(windowTitle) + sub_window.setGeometry(100, 100, 400, 300) + sub_window.setWidget(scroll_widget) + + self.mdi_area.addSubWindow(sub_window) # 将子窗口添加到MDI区域 + # self.mdi_area.subWindowActivated.connect(self.adjustMdiAreaSize) + # self.sub_window.append(sub_window) + + sub_window.show() + self.sub_windows.append(sub_window) + + + return sub_window + + + def createDeciveWidget(self): + dialog = DeviceDialog() + if dialog.exec_() == QDialog.Accepted: + deviceName, proType, masterSlaveModel, pvUpperLimit, pvLowerLimit, pvUnit = dialog.getParameters() + windowTitle = deviceName + proType + ' ' + masterSlaveModel + DeviceDB().createDevice(deviceName = windowTitle, proType = proType, masterSlaveModel = masterSlaveModel, pvUpperLimit=pvUpperLimit, pvLowerLimit=pvLowerLimit, pvUnit=pvUnit) + else: + return + + self.areaWidget(windowTitle) + + + def newAreaWidget(self, sub_window): + + deviceName = sub_window.windowTitle() + dialog = AreaSettingWidget() + if dialog.exec_() == QDialog.Accepted: + varType, channelNums, channelBytes = dialog.getParameters() + devices = Devices() + number = devices.getValueLength(deviceName) + devices.addAreas(varType, channelNums, channelBytes, deviceName) + self.devicesmanage.addDevice(deviceName, channelNums, channelBytes) + + else: + return + layout = sub_window.widget().widget().layout().itemAt(1).widget().layout() #获取sub_window的widgetArea的areaLayout2 + + for i in range(int(channelNums)): + if (i + number) % 2 == 0: + layout.addWidget(QLabel(varType + str(i + 1 ) + ": " + channelBytes + 'Byte' ) , (i + number)//2, (i + number) % 2) + layout.addWidget(QLabel('0'), (i + number)//2, (i + number) % 2 + 1 ) + layout.addWidget(QLineEdit('0'), (i + number)//2, (i + number) % 2 + 2 ) + + + else: + layout.addWidget(QLabel(varType + str(i + 1 ) + ": " + channelBytes + 'Byte'), (i + number) // 2, (i + number) % 2 + 3) + layout.addWidget(QLabel('0'), (i + number) // 2, (i + number) % 2 + 4) + layout.addWidget(QLineEdit('0'), (i + number) // 2, (i + number) % 2 + 5) + + layout.addItem(self.verticalSpacer) + + + + + + def editAreaWidget(self): + l = len(self.area.masterValues) + for x in range(l): + self.labelText[x][0].setText(str(self.area.masterValues[x])) + + + + + def getTextValue(self): + for sub_window in self.sub_windows: + areaLayout = sub_window.widget().widget().layout().itemAt(1).widget().layout() + + for row in range(areaLayout.rowCount()): + for column in range(areaLayout.columnCount()): + + widget_item = areaLayout.itemAtPosition(row, column) + if widget_item is not None: + widget = widget_item.widget() + if isinstance(widget, QLineEdit): + line_edit_text = widget.text() # Get text from QLineEdit + concurrent_label = areaLayout.itemAtPosition(row, column - 1).widget() + proTypeLabel = areaLayout.itemAtPosition(row, column - 2).widget() + # if isinstance(proTypeLabel, QLabel) and (proTypeLabel.text().startswith('AI') or proTypeLabel.text().startswith('DI')): + # concurrent_label.setText(line_edit_text) # Set text to QLabel + self.lineEditText.append([widget, int(widget.text())]) + self.labelText.append([concurrent_label, int(concurrent_label.text())]) + + for key in self.lineEditText: + value = key[1] + self.area.masterValues.append(value) + + + + + def startProtocol(self): + # self.area.getallAreaValue(self.sub_windows) + thread = MyThread(self.area) + thread.start() + + + def closeEvent(self, event): + pass + + + def deleteAreaWidget(self): + pass + + + +class AreaQMdiSubWindow(QMdiSubWindow): + def __init__(self): + super().__init__() + self.number = 0 + self.devicedb = DeviceDB() + def closeEvent(self, event): + self.devicedb.deleteDevice(deviceName = self.windowTitle()) + + + + + + +if __name__ == '__main__': + app = QApplication(sys.argv) + Client.initDB() + window = MainWindow() + + window.show() + sys.exit(app.exec_()) \ No newline at end of file diff --git a/UI/__pycache__/AreaSettingWidget.cpython-310.pyc b/UI/__pycache__/AreaSettingWidget.cpython-310.pyc new file mode 100644 index 0000000..09e93a8 Binary files /dev/null and b/UI/__pycache__/AreaSettingWidget.cpython-310.pyc differ diff --git a/UI/__pycache__/AreaWidget.cpython-310.pyc b/UI/__pycache__/AreaWidget.cpython-310.pyc new file mode 100644 index 0000000..264594d Binary files /dev/null and b/UI/__pycache__/AreaWidget.cpython-310.pyc differ diff --git a/UI/__pycache__/DeviceWidget.cpython-310.pyc b/UI/__pycache__/DeviceWidget.cpython-310.pyc new file mode 100644 index 0000000..3b0b820 Binary files /dev/null and b/UI/__pycache__/DeviceWidget.cpython-310.pyc differ diff --git a/model/ClientModel/Client.py b/model/ClientModel/Client.py new file mode 100644 index 0000000..89c4ebc --- /dev/null +++ b/model/ClientModel/Client.py @@ -0,0 +1,22 @@ +import os +import sys +from peewee import * +from utils.DBModels.BaseModel import * +from utils.DBModels.ClientModels import * +class Client(object): + def __init__(self): + super(Device, self).__init__() + + @classmethod + def initDB(self): + dbPath = os.path.join('db', 'project.db') + if os.path.isfile(dbPath): + self.deviceDB = SqliteDatabase(dbPath) + client_proxy.initialize(self.deviceDB) + self.deviceDB.connect() + else: + self.deviceDB = SqliteDatabase(dbPath) + client_proxy.initialize(self.deviceDB) + modelsArr = [DeviceDB] + self.deviceDB.connect() + self.deviceDB.create_tables(modelsArr, safe = True) diff --git a/model/ClientModel/__pycache__/AreaManage.cpython-310.pyc b/model/ClientModel/__pycache__/AreaManage.cpython-310.pyc new file mode 100644 index 0000000..5900172 Binary files /dev/null and b/model/ClientModel/__pycache__/AreaManage.cpython-310.pyc differ diff --git a/model/ClientModel/__pycache__/Client.cpython-310.pyc b/model/ClientModel/__pycache__/Client.cpython-310.pyc new file mode 100644 index 0000000..a238958 Binary files /dev/null and b/model/ClientModel/__pycache__/Client.cpython-310.pyc differ diff --git a/model/ClientModel/__pycache__/Device.cpython-310.pyc b/model/ClientModel/__pycache__/Device.cpython-310.pyc new file mode 100644 index 0000000..9a89783 Binary files /dev/null and b/model/ClientModel/__pycache__/Device.cpython-310.pyc differ diff --git a/model/ProjectModel/AreaManage.py b/model/ProjectModel/AreaManage.py new file mode 100644 index 0000000..18264a5 --- /dev/null +++ b/model/ProjectModel/AreaManage.py @@ -0,0 +1,194 @@ +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.ClientModels import DeviceDB + +jsonCon = json.dumps([{ + "id": 0, + "type": "AO", + "nums": 4, + "bytes": 2, +}, + { + "id": 1, + "type": "AI", + "nums": 8, + "bytes": 4, + }]) + + +class Area(): + startAddress = DevicesManange().getAddress() + endAddress = None + bytes = None + def __init__(self): + + self.masterRealtimeValue = [] + self.slaveRealtimeValue = [] + self.masterForceValue = [] + self.slaveForceValue = [] + self.masterValues = [] + self.slaveValues = [] + # self.id = areaJson["id"] + # self.type = areaJson["type"] + # self.nums = areaJson["nums"] + # self.bytes = areaJson["bytes"] + # self.values = [0] * self.nums + # self.writeValues = [0] * self.nums + + # def getallAreaAddress(self): + # self.masterRegisterAddress = [] + # self.slaveRegisterAddress = [] + # self.masterDevicesAddressStart, self.SlaveDevicesAddressStart = DevicesManange().getByteLengthStart() + # print(self.masterDevicesAddressStart, self.SlaveDevicesAddressStart, 'ssss') + # for key in self.masterDevicesAddressStart: + # if DeviceDB.getByName(deviceName=key).areaJson is not None: + # registerAddress = 0 + # jsonCon = json.loads(DeviceDB.getByName(deviceName=key).areaJson) + # for jsonKey in jsonCon: + # nums = int(jsonKey["nums"]) + # bytes = int(jsonKey["bytes"]) + # for i in range(nums): + # if bytes % 2 == 0: + # byte = bytes // 2 + # else: + # byte = (bytes+1) // 2 + # registerAddress = registerAddress + byte + # self.masterRegisterAddress.append(self.masterDevicesAddressStart[key] + registerAddress) + # + # + # for key in self.SlaveDevicesAddressStart: + # if DeviceDB.getByName(deviceName=key).areaJson is not None: + # registerAddress = 0 + # jsonCon = json.loads(DeviceDB.getByName(deviceName=key).areaJson) + # for jsonKey in jsonCon: + # nums = int(jsonKey["nums"]) + # bytes = int(jsonKey["bytes"]) + # for i in range(nums): + # if bytes % 2 == 0: + # byte = bytes // 2 + # else: + # byte = (bytes + 1) // 2 + # registerAddress = registerAddress + byte + # self.slaveRegisterAddress.append(self.SlaveDevicesAddressStart[key] + registerAddress) + # + # print(self.masterRegisterAddress, self.slaveRegisterAddress) + # return self.masterRegisterAddress, self.slaveRegisterAddress #按顺序返回所有的寄存器地址 + + # def getallAreaValue(self,sub_windows): + # self.sub_windows = sub_windows + # + # for sub_window in sub_windows: + # if '主站' in sub_window.windowTitle(): + # areaLayout = sub_window.widget().widget().layout().itemAt(1).widget().layout() + # for row in range(areaLayout.rowCount()): + # for column in range(areaLayout.columnCount()): + # widget_item = areaLayout.itemAtPosition(row, column) + # if widget_item is not None: + # widget = widget_item.widget() + # if isinstance(widget, QLineEdit): + # line_edit_text = widget.text() + # concurrent_label = areaLayout.itemAtPosition(row, column - 1).widget().text() + # proTypeLabel = areaLayout.itemAtPosition(row, column - 2).widget() + # self.masterRealtimeValue.append(concurrent_label) + # self.masterForceValue.append(line_edit_text) + # else: + # areaLayout = sub_window.widget().widget().layout().itemAt(1).widget().layout() + # for row in range(areaLayout.rowCount()): + # for column in range(areaLayout.columnCount()): + # widget_item = areaLayout.itemAtPosition(row, column) + # if widget_item is not None: + # widget = widget_item.widget() + # if isinstance(widget, QLineEdit): + # line_edit_text = widget.text() + # concurrent_label = areaLayout.itemAtPosition(row, column - 1).widget().text() + # proTypeLabel = areaLayout.itemAtPosition(row, column - 2).widget() + # self.slaveRealtimeValue.append(concurrent_label) + # self.slaveForceValue.append(line_edit_text) + + # self.masterRealtimeValue = [int(s) if s.isdigit() else float(s) for s in self.masterRealtimeValue] + # self.slaveRealtimeValue = [int(s) if s.isdigit() else float(s) for s in self.slaveRealtimeValue] + # self.masterForceValue = [int(s) if s.isdigit() else float(s) for s in self.masterForceValue] + # self.slaveForceValue = [int(s) if s.isdigit() else float(s) for s in self.slaveForceValue] + + + + 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 getValueLength(self, deviceName): + number = 0 + if DeviceDB.getByName(deviceName=deviceName).areaJson is None: + return number + else: + numbers = json.loads(DeviceDB.getByName(deviceName=deviceName).areaJson) + for i in numbers: + number += int(i['nums']) + return number + + 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 new file mode 100644 index 0000000..d3a51f0 --- /dev/null +++ b/model/ProjectModel/DeviceManage.py @@ -0,0 +1,99 @@ +import collections +class Device(): + areas = [] + startAddress = None + endAddress = None + protocolType = None + masterOrSlave = None + def __init__(self): + pass + + def addAreas(self): + areas.append(Area()) + + + def getValueLength(self): + pass + + + def writeAreas(self): + pass + +class DevicesManange(): + def __init__(self): + self.masterDevices = collections.OrderedDict() + self.slaveDevices = collections.OrderedDict() # 有序字典 (OrderedDict) + self.initDevices() + + def initDevices(self): + devices = DeviceDB.get_all() + + if devices is 'error': + return + for x in devices: + masterSlaveModel = x.masterSlaveModel + if masterSlaveModel == '主站': + devices = x.deviceName + masterByteLong = 0 + if x.areaJson is not None: + for y in json.loads(x.areaJson): + numbers = y['nums'] + bytes = int(y['bytes']) + if bytes % 2 == 0: + byte = bytes // 2 + else: + byte = (bytes + 1) // 2 + masterByteLong += int(numbers) * int(byte) + self.masterDevices[devices] = masterByteLong + elif masterSlaveModel == '从站': + devices = x.deviceName + salveByteLong = 0 + if x.areaJson is not None: + for y in json.loads(x.areaJson): + numbers = y['nums'] + bytes = int(y['bytes']) + if bytes % 2 == 0: + byte = bytes // 2 + else: + byte = (bytes + 1) // 2 + salveByteLong += int(numbers) * (byte) + self.slaveDevices[devices] = salveByteLong + print(self.masterDevices,self.slaveDevices,'分别返回PA和DP度') + + def addDevice(self, deviceName,channelNums, channelBytes): + channelBytes = int(channelBytes) + if channelBytes % 2 == 0: + channelBytes = channelBytes // 2 + else: + channelBytes = (channelBytes + 1) // 2 + if deviceName in self.masterDevices: + self.masterDevices[deviceName] = self.masterDevices[deviceName] + int(channelNums) * int(channelBytes) + elif deviceName in self.slaveDevices: + self.slaveDevices[deviceName] = self.slaveDevices[deviceName] + int(channelNums) * int(channelBytes) + elif '主站' in deviceName: + self.masterDevices[deviceName] = int(channelNums) * int(channelBytes) + elif '从站' in deviceName: + self.slaveDevices[deviceName] = int(channelNums) * int(channelBytes) + + # print(self.masterDevices,self.slaveDevices,'分别返回PA和DP每个主站寄存器地址的总长度') + return self.masterDevices, self.slaveDevices #分别返回PA和DP每个设备的字节的总长度 + + + + def editDevies(self): + pass + + def getByteLengthStart(self): + masterAddress = 0 + slaveAddress = 0 + masterAddressList = {} + slaveAddressList = {} + for key in self.masterDevices: + masterAddressList[key] = int(masterAddress) + masterAddress = int(self.masterDevices[key]) + masterAddress + print(self.masterDevices[key],'dddd') + for key in self.slaveDevices: + slaveAddressList[key] = int(slaveAddress) + slaveAddress = int(self.slaveDevices[key]) + slaveAddress + print(masterAddressList, '主站', slaveAddressList, '从站') + return masterAddressList, slaveAddressList #返回PA和DP每个字节长度的起始值 \ No newline at end of file diff --git a/model/ProjectModel/__pycache__/AreaManage.cpython-310.pyc b/model/ProjectModel/__pycache__/AreaManage.cpython-310.pyc new file mode 100644 index 0000000..a0d011f Binary files /dev/null and b/model/ProjectModel/__pycache__/AreaManage.cpython-310.pyc differ diff --git a/model/ProjectModel/__pycache__/DeviceManage.cpython-310.pyc b/model/ProjectModel/__pycache__/DeviceManage.cpython-310.pyc new file mode 100644 index 0000000..f090a26 Binary files /dev/null and b/model/ProjectModel/__pycache__/DeviceManage.cpython-310.pyc differ diff --git a/protocol/ModBus/ByteOrder.py b/protocol/ModBus/ByteOrder.py new file mode 100644 index 0000000..8696fef --- /dev/null +++ b/protocol/ModBus/ByteOrder.py @@ -0,0 +1,40 @@ +import struct + +# 大端模式 +def floatToABCD(value): + valueByte = struct.unpack('>HH',struct.pack('>f', value)) + return valueByte + +# 小端模式 +def floatToDCBA(value): + valueByte = struct.unpack('>HH', struct.pack('f', value)) + return valueByte + +# 双字反转 +def floatToCDAB(value): + valueByte = struct.unpack('f',struct.pack('>HH', value[0], value[1])) + return valueByte[0] + +# 小端模式 +def DCBAToFloat(value): + valueByte = struct.unpack('HH', value[0], value[1])) + return valueByte[0] + +def BADCToFloat(value): + valueByte = struct.unpack('>f', struct.pack('