From 4c8045360640054873871a59729895578bdb1c5a Mon Sep 17 00:00:00 2001 From: zhangxuxutm <951937200@qq.com> Date: Sat, 2 Sep 2023 20:38:25 +0800 Subject: [PATCH] 0902 --- UI/AreaSettingWidget.py | 48 ++++ UI/AreaWidget.py | 61 ++++ UI/DeviceWidget.py | 55 ++++ UI/MainWindow.py | 270 ++++++++++++++++++ .../AreaSettingWidget.cpython-310.pyc | Bin 0 -> 1730 bytes UI/__pycache__/AreaWidget.cpython-310.pyc | Bin 0 -> 2288 bytes UI/__pycache__/DeviceWidget.cpython-310.pyc | Bin 0 -> 1893 bytes model/ClientModel/Client.py | 22 ++ .../__pycache__/AreaManage.cpython-310.pyc | Bin 0 -> 5160 bytes .../__pycache__/Client.cpython-310.pyc | Bin 0 -> 1061 bytes .../__pycache__/Device.cpython-310.pyc | Bin 0 -> 1057 bytes model/ProjectModel/AreaManage.py | 194 +++++++++++++ model/ProjectModel/DeviceManage.py | 99 +++++++ .../__pycache__/AreaManage.cpython-310.pyc | Bin 0 -> 3294 bytes .../__pycache__/DeviceManage.cpython-310.pyc | Bin 0 -> 2993 bytes protocol/ModBus/ByteOrder.py | 40 +++ protocol/ModBus/ModBusThread.py | 32 +++ protocol/ModBus/TCPMaster.py | 131 +++++++++ .../__pycache__/ByteOrder.cpython-310.pyc | Bin 0 -> 1212 bytes .../__pycache__/ModBusThread.cpython-310.pyc | Bin 0 -> 1122 bytes .../__pycache__/TCPMaster.cpython-310.pyc | Bin 0 -> 2212 bytes utils/DBModels/BaseModel.py | 29 ++ utils/DBModels/DeviceModels.py | 70 +++++ .../__pycache__/BaseModel.cpython-310.pyc | Bin 0 -> 1201 bytes .../__pycache__/ClientModels.cpython-310.pyc | Bin 0 -> 1713 bytes 25 files changed, 1051 insertions(+) create mode 100644 UI/AreaSettingWidget.py create mode 100644 UI/AreaWidget.py create mode 100644 UI/DeviceWidget.py create mode 100644 UI/MainWindow.py create mode 100644 UI/__pycache__/AreaSettingWidget.cpython-310.pyc create mode 100644 UI/__pycache__/AreaWidget.cpython-310.pyc create mode 100644 UI/__pycache__/DeviceWidget.cpython-310.pyc create mode 100644 model/ClientModel/Client.py create mode 100644 model/ClientModel/__pycache__/AreaManage.cpython-310.pyc create mode 100644 model/ClientModel/__pycache__/Client.cpython-310.pyc create mode 100644 model/ClientModel/__pycache__/Device.cpython-310.pyc create mode 100644 model/ProjectModel/AreaManage.py create mode 100644 model/ProjectModel/DeviceManage.py create mode 100644 model/ProjectModel/__pycache__/AreaManage.cpython-310.pyc create mode 100644 model/ProjectModel/__pycache__/DeviceManage.cpython-310.pyc create mode 100644 protocol/ModBus/ByteOrder.py create mode 100644 protocol/ModBus/ModBusThread.py create mode 100644 protocol/ModBus/TCPMaster.py create mode 100644 protocol/ModBus/__pycache__/ByteOrder.cpython-310.pyc create mode 100644 protocol/ModBus/__pycache__/ModBusThread.cpython-310.pyc create mode 100644 protocol/ModBus/__pycache__/TCPMaster.cpython-310.pyc create mode 100644 utils/DBModels/BaseModel.py create mode 100644 utils/DBModels/DeviceModels.py create mode 100644 utils/DBModels/__pycache__/BaseModel.cpython-310.pyc create mode 100644 utils/DBModels/__pycache__/ClientModels.cpython-310.pyc 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 0000000000000000000000000000000000000000..09e93a855e1c067de1dde8b43106f0e2c605576b GIT binary patch literal 1730 zcmZWp-D@O85by5!*xAqQ9jJ#020>&5^L8&m#C&)XId?B6;b2%8Cexi{aXm9M0GeZA|nc3*iu2ReGLCe zTw9kG=c6D_*L8LAMk>2EgPpXmbb0Y+l!$kDgyLMrgmc=W~bw~snKnXW~v{j9UH(76=Zks4tB}aB zarPDy+(8?@hFfmAre-q>9-C=vHV@zVwk~Z2a(SmGbTxz$Cn9e3yP2+?D6>0CWc>-q z`RM+aPY(~D{PgS5cc1_L+rxehY{wrxJpTCW#}9r)LmdzO@XgcDJ~@8y$I&m}PoFz- z{OSECzaP3yiLjB-lSDfK=L<@}f7LUg+N+x)RIQ*ZBvxA6u=_!}EwS{PweM(qE=WQV z!?iFJJtep4wn9f}v7re%JJA6$g>K|DXSuOvz%!ez3+cF)F0VoE za~o02$JMWfeThA{ECy;^aZ`clnnhVI+`mu)U5ANqE0FM53R?43EQSNDN%2=*tnmA|&7hCPKycyD9I-DA#=d!+sEtcZ#kpYA#*4r0XXG0-zB4{<**qqOy1( z3;Z-Bs z$qFa(byUqju5W20==HR{UBC)v*+#mpO)-GkZHa*h&xd!0AMLz3&h#yuFd0TXNgUQ> O&T9Z6>d>py{O^C0Q^U&u literal 0 HcmV?d00001 diff --git a/UI/__pycache__/AreaWidget.cpython-310.pyc b/UI/__pycache__/AreaWidget.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..264594d0586dd82a8fe9abf7602318bae051f018 GIT binary patch literal 2288 zcmZWqOK;mo5Z>imv}DV&ET?(2Zqq{rv<6zVmm&!2JYgVqEyzKNg#d!$ZfrVSQe9Gh z2=Pe)l0*9w3dp?$z4hntTA+XrJ@!_hogtZ2P9*H?>~c8oZ+h6==n~*>7 zF#j{)@Exr5cOaZ_8WBkul^WBe&U9%oLz>K#7PF+yZ0RsZ)>uut%#{mlLDpGaHdsS0 zvPHSXmSmGP8Y zFp2Yp-nJjcPr{fd$GOwnOOoi0uYlX;;ieLPZud5WLbBf5ibvz@Ug$^3K3rGKLhnJM zSAH(%nQ3lk#rQAEJG? z2Tb*Rq4!XQys}{R9{EENf#191^q|xRhyKV9gxbo4#6vg{y9tDN+NJq2M$s2p7RLLf z!kqv!G5^!6L;5u^f-uSn(_WINlvA#~aG1_@ZoD82>cB17O>T1scIzcE2($a7TgzRv zQyK{9oO0wfSZE{d0LjRd%qUjsIhkp=bJ8cT=}uSA&2&5xkbTb!<1q8Q+`|3w)@zy@ zsfeD!Uh}*l^3&AwUX#D?g1)=o4j!jMrGv?VAMc-xPsW4qV{uP~M`Hbp_3i$Hy}_U7 zKVAIt>tLjkr{Qp%4jyj}{`YocbgHg`9tR!7E_Z32PFCgw-gxs~T!51*E{GE2dPO{% zX~nK*MzNc($e}s2fa=(fna$~xf}8`KR&X_ZHgkbGkZ1i|r=X|0sbS`;8|QFgRxhf8 zRd7%n$kp%`_C|G{(*(FN&dqnU*>7&MMegugwshEpwLCSzr&eKi1!xQH&Pmp|gHkA6 zNVeZfwn3_ptt`>mDm*g_>_J_-?hey;#Br|Q6OqDZxIpq=3*zMptkePm3gA_B1z6}{ zI~K=S4Ydwubsb5;eGFXg+=_fTsfA>S&A9)m++we}^_{NAKuut)t;; z>62n;l=?Qx1YYWW6SN?n5q{}cKr;9qOtHJ^l$_D$6mgyDhX%~)H8`2)WT2mEXZo3e zSjW}XcGOLHvuow%NQH5xa5m(oI1z!T5R19983baKLE;)PCU<@1OOXN4yQaDU&)Ks7 z?qthdE{?)L?0{r$1KjscN5CBU3YoHN*5OrEB;`}!K8Ka!htHuFU4 |4v$S-BY#R zrRcF$aTU?yz`%HlW_`Cq*WqDl3+>==EjrYomuytc&~__F3VpJ9NROr7##d)KeiGheB&zp<$Llh~3T>}osRT(U)Q^#=Dn~uVJv@78&=y~0b z@}=F=UiQsKuWF}MAx;!lTVbpUYp)Qb3e^>rQZ?i-iv@-hc3OcJwTRpjk|q)alxiVC z%&52BU)EkvPt(F5g_+6?U+o{|x<4A_0J`G)Y@`S9l{Umln5hlauzs0fq%aZ6%-zNs WrD)>^Qr8@lq|_gle8i9U?>!HsOhDpm{MBXNijJ7sBHp^V39RrXWf-no!#{p zo0AQOx{h<{A%_;J^bk`p^cHa2KV+`8leni|dhdI)vMLwa74!D}=IzY9dGGh0qH?)N z;Q3?WPkz@WxTE$Y!0^H|I9jF#z{Ez7eg+E{3N_UD8f+}tPJ z6m-w<9L|+Bf4v0xS8+F5w%vgkL%I-9zXeTFB6@0%LHsaX#Psm^QVCSic`bsQhT;F}vXs>Ul+i88i zEv99#DaPI#d$4qWx&E^E&EV3*PcEO(;l~u`c5f#&xFe%(@0QP}5c;Gr$U=?OP47 z+S+QuS~D{NI|FQG7GQUP?aT&T7+@!J02dKwv}^H^jP+PwFJ;C+FK6aJuVmIhAIPXAbp@qc{Eb{MVz2-RexclO|&e4GAuR zuW_v^k@3<3;kgaYXA;qhRXG;P{OX2iCg{6Fx_CBNzlgRZUS6^JFFkvz(Qb+mmNlEA zlL)SyX4G!OB4y`Oo+|}zBDiPgnkvA~{RU70^I87NemnsRIfy2`Yut9#l~eYO0Tc*BUd8v7%Vl1iR74z;BJs zJ_e3!Z1pklTw^;kGMcf>%&g2_!*=G($(wNQe})K}Z($8WJoP9Dd7k8vW-75OEsO0$ zCsvsWs5M7NUyl9XcK?d9DnlRohfD9n(zpVmN{4^Dcdy0q+7b!>K5z@{p=}@<^w6U3 zw<4Z~sF!^ItF#g37TxT0UgbNmNR|676&M)${*Y(rfz%|x{2;MoJjEpy>YCMeCC=7d zHM+2~n0zq42o%J28cXc{c`+c}b+B@-8}Ux8R}CF9V48A2&i(xadu)t!c$>KF7W*5M CRpZG3 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..5900172838c8905619e03af6314d47017f87c6be GIT binary patch literal 5160 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 PVBWR=H8?of9C`M?RJEF+ literal 0 HcmV?d00001 diff --git a/model/ClientModel/__pycache__/Client.cpython-310.pyc b/model/ClientModel/__pycache__/Client.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a238958771f703b91e2e8b62232056302ca44db0 GIT binary patch literal 1061 zcmZuwL2uJA6!vq{H0#=erX416U`L8Xe*l^gbQPRdkX9~HB`ZzbEtQvawllh_J9W}7 z@Dq?)Zu?6vVl5zn-<%YN<@GPbA4n@LK9l-{f#g@;0Y6p!b8s=m{mvlt{ zlf{$JYdNN(@(Gv5>+*{v;>KqzNfXT&rsygzMz>(L7>h)x6l1sKR}Z-kpAX(EF4bUm z8m1@He3}p5ro1bY3%>ts|LFL2fAD?v@$U1N!9-@GWSFbLSr&6KC=)%}!0pMU^pLV@ z^F-~*4$K~uVeR`={(6{wkgdm|JupS1$rzT@O0=R^P$#3mcQ!z+WWLT>d+N@+X0G~0+U4W#XM?5f&D)1-B% zK^>Y_D;Fs>&v=8An|z<4rjKz`5DWbs|)|+bQ}; twL2(d0nMX-b~f4#k7q+$rh<1PjY6M78vmet*$eyMQS~AhAIje@{00Ue3nKsk literal 0 HcmV?d00001 diff --git a/model/ClientModel/__pycache__/Device.cpython-310.pyc b/model/ClientModel/__pycache__/Device.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9a8978309a84053623fc2372fedf974aca06010e GIT binary patch literal 1057 zcmZuwO>Yx15cPOJvPqL7Rh2;EK#v58{s2@VNFq2jAT?Z8k*v+G({AMMruL?!QF=R2s*qe%g@XF&Ed;I+TJexNfHG=Kt>(Ar|CFGk4Hk*sVE9~k3 zO+pe7BrHb=0b?p?&%{(X>(T9zw9rCC}qhWuQ`#qbt%m9bbvN-=gzeswXc{i6RtajE*VlPEi$ zPNtLoyNq{add~Nr?;Re!>Gi*_KHYu((jUuwm<}eYf0`#;^xGokS#fCnlJWldLV5^U z!LCqvvIDaR>!o`tf8ENkG>_3X8>VOqGJ+*F`mE?B*vOf~3gnZ*ox=ie%)G*1R_0{n ztpJD_m%+UP|IaC^$8bsiWEyW&n^U9x4P9&Jbu~=}v+9~{GU!>&q9Jc?X__nTj-%p4 zyQ4hKw4bVBD!AT0IumKZJ5do0BE`cXu@Bd2>3VF%VJO-3Lf6bIq>)HxTvy^e%XnPq zpganb8?oe3!5N|mu9}YYQ3))t!FxP1tXj3zYbj+F=SySi8)+bHr)7M#i)NeFp$2u> zh8lW4`nxb|tZ!82HY=tmvgnjErfZBL_Cy%J&e+)`66K10M7?F} qGFn$Z{%2*Q+HiY57@>w1cY}u2$4V0%ls9{6{u@=dTmmS+UHA=x{Rig& literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..a0d011fb2431f2ab4ca22df636868828ee698cc1 GIT binary patch literal 3294 zcmZuz%WoV>9q#Ja^z@9!6UTAlO?KnmMavGb0||t{vVdP?3D{oGjv-RXXlPGWCT+T> zC)GWPZN?|BI3QNq14od?oXC|ke@P#>AR+mT;D916->-W7%5Jyn>w5g^_5EI*OilR) zo_BBkTim;C82_Zk#m7Tq5heWxKp28W1~0yhGu<}1iLV)1vCZw+;ZE#wH!kr~>~SwH z^K$HSKd$gfT;bf1>ieKli>$(%Y5#Q#wnIVnw0_0p#5}qjk$riq-h$>pB_snC) z-~7-JQ=;~XA!_d zG162nLG}?opE7ikH#?%N8rr$tv#(suzpV`Ov+WV&u@v^3fp9bvSM7i^>9!Y1`aKbAq1g|Yl)5DjHM zlSaWad8rSEtOcRwZXv~|wbXe>UM)oQ8fjk9!$so-%k5M~k6#$-Jsj~rZ94G#+rLPq zO1BT5fcL%O-f;V)zFbw|Gr92I!g~9`*7m=S|8Vl>zibaw@;KZXrrU8MWVF4hl3m%& z)^&pjAeReQK(#=zuFVN`Fsc7OFAVVY&=8*|9 z8S2)gZf4fV*tLayWHJ!F%f^mygiC$LmhLgndR*!usvD(^gYuob_nY6sdpGxE>* zimXC?oq)(MfXpwiXz4;lzePt%k+N!5S(VMOId)Ljd|eP~_(X9(h-Igf`<)IHGK{ER z?R1_FgQyr$H?R!%;nhn*D4C{tHO&Hb*79XvOh(jO5LMqKxI=J$KwYC#s&@c4QM5ii z!)G>Lk5#wz$QL}!g6JZNuL4dztY>fwer2OLJ>xMn3;!ZtEBvcOQC0gJBCGZ{#8!NL z?RV9@G>H)#U2?V4hju!%nK#fFu~p+&{vm8;*BG}1~ zG*ps%vOCOV!_!==1$3%63A7E8jC!AdHrCs|!abBC1bIaIM@Xa#fEi|*CZpGXIa{j3 zE{m4QyqCVa01rA<&FR!j21IH)Gaw2&f*qQgb{OcHdZtEZn}{tGG8qBI*2vQ4W{=Fw zfkLf$D!wdxr5l3D8y1S9$v!sogj*| zp-fBynPrO-_$0ZtDedXJQkb1R@yfzTK|z$Wy;oVNV%?=EDlYjq?4&vHaQh-o-NN@^ z_5ufI!j~AJuunz1DbaBjGKvkqEPnesG;5RmJ8ewC37gHFZgxHl54wv%^=*Rh5PXl| z9>I4BbO?SxwVxAwOh8%s!fnqZ@_h{a9wnUtc-WHOs^!_T zuJN0h;&%!E82R+(ek;4zY-PniSgPpUilV8aiz{*oMe$9MNhk_ns!TxXNmU3awW}!t zGB`C&P$#%TK*v&731$hd5zG->2k_haH==p*H=1!UgktH~M69%z7Oq*LP zo9j9o>(rdz9A;sZHdmLmy`;^RD3tx;rz9=hY?*e{5#=4K5h-8BX6}7}10jw6h}55c i4d5AMKEF1r7Nuf)5@JkdzcfolfU#e?|EtwzlK%tGE)$FZ literal 0 HcmV?d00001 diff --git a/model/ProjectModel/__pycache__/DeviceManage.cpython-310.pyc b/model/ProjectModel/__pycache__/DeviceManage.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f090a268e940f1334538e3eb78903a03aea1beb5 GIT binary patch literal 2993 zcmbtWOK%)S5bmDW&OZFa#Bm6UV-&~|kqa*=vO*jzkWjo1a+1T!XqjwxHtVcs?e19< zTeAphqbNdwL&OCkP|N`-${#@Fz#rfj%oPmy9OceeJ-h2?1QIjqnyP+Pb=6nZ(;OJc zF+BC-PsP*_W51KI`>`QhK+~r|1QWc$%IrfXEMeba!tPjQ4#^QNBo~q;_yQ|>+nCKt zRie8e3&I67O+>OX7p!d6SlJf5?4Y@59$F^dzwDSi=i8m|P z>Qz~)a_rZ8h^O{G+EWKaum$#rmmYy6j+TuZ%0;gs&#uzMbBkBCRC;maW)RkHw{Eu< z=R-NG>T7cHjmf!%53Vf!xp{y4`yUrqRP#ptdP^@ZH-&60URKQ|S&in5keV_Vgh5T7 zU0F~3N~Ipwqe{gmJLu#N-xx|~o$ZYsFr55NhU;OFh&|+y)nS{Qn?oo%P0>!=K*>NS zUa+zvLy}nP3y|zK7k1kL z=Lpu~YA$jgdL(Vqir3n1>Ua1UdzZDH)l;z(vn4;~(`>Z>8+@#P(6=Gmx8bWjHk|rb8$N%I4cXL&*f;vK ztF<@_{n=E1lry$K7TJ!S#<-X(C9YJesh*KX|M>aIUyr|4R0|R(Y%S}=y}lkvy-mQ` zrtWmwldmzYbp-O(y}MiY9{>I8H(THRaCv6y!Ts6GTfh8N%qM;t$=QoZ2GyVvG#bfp znolO1O!-W5A}!@eTa+!-tdDdvOq?a6Zlf6po!Ip-QWMamj)5fZib6**r!pjE()Bvw zx78_hlm}B47h&|JW>`!3dXm98uA|Va6STsi^OOg4&{&hbS-Y~>B=Ad^cpOci2SL(W z4)?idngf^)gDc<#V67wg(%Am~QH)w&jPZ?Q`vAQwDXLW1dk^u{45ohr6S3F^@(8&c z$RqR)5f9|qKprXrkY}WrBd&ansWbGA`2?-CfJC#y7#l~9Q~xvz-!^kC%$-4>^_;or z$J`UbiD}o5_wLr;Ye=|e{L=&DX1$pQ9XBlcH7Kb`oXG%7oh0sMB2yqmTfI(vKg31H z#8$nEUeq4k&Y^6S2#bZTKylOif|g`)v!%X%4+}Mcg~CKZ%JC_Drx2*4Xb73Tadcl; z`il>gOaeUx<-gpEIVsYTC-nj?F?Zs`K2|d?sa_C7TX`Xh) zOLZNUhj&k)p2WT-*Y}5c6vf2kt@-m ZHywxVk@(Z;Z_9ZCow*i$HpoZE{sCK9jmH20 literal 0 HcmV?d00001 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('fgc5Z(3KiPI+i<|80bxghlb5)vmAMZ~tM9B6WAxKzG`j8iI19F6U&Md8Mg zzko!zq@4+0O*&V&6& z`$xxz9sk?-{S|bkVL&G^p7HN=*%hG2mwAGUS{k4FzP0qsNuMt$pqN! zNmJqm1^?xVOq%#0wO`DPS|2S6u*8OI%}s@(1%l@~4Sm1K_uFKaW}m5Avx!{M^7Kx_ zbGc;H>33I2k30N+Yo+wA*Kjy#o__CN>6x6?z(WfD)Bvce7zr?|VytpC@E1~q)ynB{ z8<9mdWpfQ%o>M0};!aY&xQ&W^!I zB59ulH$4sLD9I2_uoRd4km*OtlD2ftSYSg`lL8_~*^}A@p+q^?-kyl- zyz+HfKcf_8wae|hQ_^4x}-bMXfWd%3!Koxe@S8C`} zEugOCSs8p(g{AYvgCN602GCr}u14M*9vt65c0&c!)Rd^U$@|79I;K6)1K!l~m`*Ij zdc;u^ja&dB(l6>N$p=bDMio4X03YwAapJR}QE3*IADt@sAFi93bXZ;N3N*`*174`0 z>@&X_t<7=&t84iVYL8t(dp8URsm%KrdtrE#NB!!g6iF{bKYbewzJ~>agEW#yEz8Ri zL{MRScKH=245By*!;z@qH8*qvO6Te36#pKry*P;tJj*6lH!G69Ti%Rbf&y)$!BTw( zOi-&zHfF&l$Y~;N^eUVd_E5)(S%6uhE`=3ODxOdAb!7L!0AMEQDigO*WsGrqjQ{xy DN@@Aq literal 0 HcmV?d00001 diff --git a/protocol/ModBus/__pycache__/TCPMaster.cpython-310.pyc b/protocol/ModBus/__pycache__/TCPMaster.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3f07fdd69a3d39299f8136d539d45a513786fb9a GIT binary patch literal 2212 zcmb_dTW=dh6rS0;FEMGFmR@M7paK@D7OfCSfJzfPO@o??VwZ|h&}#8a+)dYBcXpg6 zmR%vWkCcCal$0m_3BO@pk&yC;5FjC-oUtr(aHXDo^(9;13PB@JT%YSLdU?xS~h)Ks{R>x*`X4BYVPBzzNF8rFY*CdOC zTikv^xc%5*1ySVAeM5dM3f$!$cuH-;3(qJki_+c{FLENv`xu=zvhJ4-V12UU8@kv@ z_*eZjP_3S}??5H^zgJ=__4W*lCHLijuBxX)6`+rgZQhF8+gxABZf2_S-6m+D99AQX$ig!M(8C z-s$i3H&(l%E~9O6>B^<$#?9u&&->pTeD`dlCzH(xa*T>fT1mXIobY+Do3*t(HPzm( z_JSblMk)wO5In7bFz7U$p%wVNuZ`z}nMo$AKkl2RiRW-w;hC>OOd9!4AAxZD%cL=zL2lLp|w@7&Ch9Tey(2AR;@lae}Kqq zTS%Emprx5ADKS^t6+5EUS3;YuRIxL6*O!_L!SbEk&84;53&Hxr;!>lzu-;&$%{U2F zGr^2c3|wVm;9?U4*OUcV!1pBLq1`kNx5W}??%}psDc|&j+ zoI@`8%F5YwI5X$d`(w^cyvV6ffp-}bCter4i@?1jUP|zTvVgS*_+my~B`It+%TUG) zIfLd&6tgIxN+U!_1$hR=SrF{>`odg2xV3t_zO=Gs2!+1{gz^9$L~Qke-Em7?N_l3WJ!{5!oOHSjo(jA!#v@~%X+Gg3v#}cV{+f(huEZCcn+h&ir;}wpdtb5Lhcuo{A9) zK?KdoE|GLZLiU;nCip24T=EeQ9pQ9I;9h_q38yqCM<4IVGU)`a@#DCk9LP8}jW|9iM3p0M#qrlF$)}c9nrE_K#sgIx9f!V1%A^Mz z&WZ9Nk5zv+BLX5HnqFbO&=ouLk3hnEXbJ~IC zI666$0W&YU8n;Z|~_W|OZ0I3Z^s`}Bl< zVPks6E{Uin7z1wjXIUDSiEt6RCn06l*JaXA(IOlX#X(^Ry$Z@FZOV9KA`bj| tZE8K>J%!#t%5PGJ?mK)e3dh&DcDk+0zoHxe`Q+ifz>aCm;}egq^1rz(^yB~l literal 0 HcmV?d00001 diff --git a/utils/DBModels/__pycache__/ClientModels.cpython-310.pyc b/utils/DBModels/__pycache__/ClientModels.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..50fb3bf6766e4e4743125f33e1179c7e7c4e0ba8 GIT binary patch literal 1713 zcmZ`(-EZ4A5a)*^ONx^wU7B^DNU^$r2gG|`FbqYKb;FQ&7@VT0V8GK%rdBH3Dk;aY zp%ep>$35&H7!dC*{}NvZ4Cr&Q=k1PaoGi#l@y9!o;@$mt{lyv3JR+oVTmxY6X{BA?jI{?##f}E3r9MYT>^pw72Gy06Qh(mHdc|get zqhuQ9PQgxL+#}C{(-ZcZwchn(Iwp16thrm06w)2gc1* zGRW)P@NTM=2gVJR7erM-`uj(K?alU6EtPIhd-34K@#uKe{$U_@RB|NOH`e!BPxjk? z&3=9J`ycI04G)r^N4h=AlT^2Nw(Obc_I8@cL0&42Y+?fNX={SsdDmQlx`K4g$TI@K*$|ZFhE*x zKvp<_yzl^>!Uc4T3ZR!)@P=6oWgqxg~ zdzF-Kzyf_2zyrRo>Kd)G=@skO|M*|h)jc$}hVVWD9_LNlVFF>6mcNAQ+bz@Sd-L3z?JxOFLZl%VuV)?PuJOC%mLN|@I z?#sM46lw{*UPY)OJVLl4&`OxO3RCS4H2o=ne}g`cG9FUqhjcZlR_$7N;kce?xIkLr zFOio?IhJsohnOAr?ZeQxd>9(@cUy5-Y@964d&Y|)fd<0vcbikj|Egr=Yl@!XvHHY^ MtAw@6pwd