0902
commit
4c80453606
@ -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_())
|
@ -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_())
|
||||
|
@ -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
|
@ -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_())
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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)
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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每个字节长度的起始值
|
Binary file not shown.
Binary file not shown.
@ -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 floatToBADC(value):
|
||||
valueByte = struct.unpack('<HH', struct.pack('>f', value))
|
||||
return valueByte
|
||||
|
||||
# 双字反转
|
||||
def floatToCDAB(value):
|
||||
valueByte = struct.unpack('<HH', struct.pack('<f', value))
|
||||
return valueByte
|
||||
|
||||
|
||||
def ABCDToFloat(value):
|
||||
valueByte = struct.unpack('>f',struct.pack('>HH', value[0], value[1]))
|
||||
return valueByte[0]
|
||||
|
||||
# 小端模式
|
||||
def DCBAToFloat(value):
|
||||
valueByte = struct.unpack('<f', struct.pack('>HH', value[0], value[1]))
|
||||
return valueByte[0]
|
||||
|
||||
def BADCToFloat(value):
|
||||
valueByte = struct.unpack('>f', struct.pack('<HH', value[0], value[1]))
|
||||
return valueByte[0]
|
||||
|
||||
|
||||
def CDABToFloat(value):
|
||||
valueByte = struct.unpack('<f', struct.pack('<HH', value[0], value[1]))
|
||||
return valueByte[0]
|
@ -0,0 +1,32 @@
|
||||
import threading
|
||||
|
||||
import threading
|
||||
import time
|
||||
|
||||
class MyThread(threading.Thread):
|
||||
def __init__(self, area):
|
||||
threading.Thread.__init__(self)
|
||||
self.area = area
|
||||
|
||||
|
||||
def run(self):
|
||||
while True:
|
||||
self.area.writeValues()
|
||||
time.sleep(1)
|
||||
|
||||
def stopThread(thread_name):
|
||||
for thread in threading.enumerate():
|
||||
if thread.name == thread_name:
|
||||
thread.join()
|
||||
|
||||
if __name__ == '__main__':
|
||||
thread1 = MyThread("Thread 1", 1)
|
||||
thread2 = MyThread("Thread 2", 2)
|
||||
|
||||
thread1.start()
|
||||
thread2.start()
|
||||
|
||||
thread1.join()
|
||||
thread2.join()
|
||||
|
||||
print("Exiting main thread")
|
@ -0,0 +1,131 @@
|
||||
|
||||
import modbus_tk
|
||||
import modbus_tk.defines as cst
|
||||
from modbus_tk import modbus_tcp, hooks
|
||||
import logging
|
||||
import struct
|
||||
from protocol.ModBus.ByteOrder import *
|
||||
|
||||
|
||||
class TcpMaster():
|
||||
def __init__(self, host, port):
|
||||
try:
|
||||
self.master = modbus_tcp.TcpMaster(host = host, port = port)
|
||||
self.master.set_timeout(5.0)
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
# 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'):
|
||||
try:
|
||||
valueByte = []
|
||||
for i in outputValue:
|
||||
if '.' not in str(i):
|
||||
valueByte = outputValue
|
||||
self.master.execute(slaveId, cst.WRITE_MULTIPLE_REGISTERS, starting_address=address,
|
||||
output_value=valueByte)
|
||||
else:
|
||||
if order == 'ABCD': # 大端模式
|
||||
valueByte=(floatToABCD(i))
|
||||
elif order == 'DCBA': # 小端模式
|
||||
valueByte = floatToDCBA(outputValue)
|
||||
elif order == 'BADC':
|
||||
valueByte = floatToBADC(outputValue)
|
||||
elif order == 'CDAB':
|
||||
valueByte = floatToCDAB(outputValue)
|
||||
self.master.execute(slaveId, cst.WRITE_MULTIPLE_REGISTERS, starting_address = address, output_value=valueByte)
|
||||
address = address + 2
|
||||
except Exception as e:
|
||||
return 'error'
|
||||
# def writeSingleCoil(self, slaveId, address, outputValue):
|
||||
# try:
|
||||
# outputValue = int(outputValue)
|
||||
# if outputValue in [0, 1]:
|
||||
# self.master.execute(slaveId, cst.WRITE_SINGLE_COIL, address, output_value = outputValue)
|
||||
# except Exception as e:
|
||||
# return 'error'
|
||||
|
||||
def readHoldingRegisters(self, slaveId, startAddress, varNums, order = 'ABCD'):
|
||||
try:
|
||||
if order == 'int':
|
||||
valueByte = 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
|
||||
|
||||
except:
|
||||
return 'error'
|
||||
|
||||
# def readInputRegisters(self, slaveId, startAddress, varNums, order = 'ABCD'):
|
||||
# try:
|
||||
# if order == 'int':
|
||||
# valueByte = self.master.execute(slaveId, cst.READ_INPUT_REGISTERS, startAddress, varNums)[0]
|
||||
# else:
|
||||
# value = self.master.execute(slaveId, cst.READ_INPUT_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
|
||||
# except Exception as e:
|
||||
# return 'error'
|
||||
|
||||
# def readCoils(self, slaveId, startAddress, varNums, order = 'ABCD'):
|
||||
# try:
|
||||
# value = self.master.execute(slaveId, cst.READ_COILS, startAddress, varNums)
|
||||
# return value[0]
|
||||
# except Exception as e:
|
||||
# return 'error'
|
||||
# def readInputCoils(self, slaveId, startAddress, varNums):
|
||||
# print(slaveId, startAddress, varNums)
|
||||
# try:
|
||||
# value = self.master.execute(slaveId, cst.READ_DISCRETE_INPUTS, startAddress, varNums)
|
||||
# return value[0]
|
||||
# except:
|
||||
# return 'error'
|
||||
#
|
||||
|
||||
|
||||
|
||||
|
||||
# print(cst.READ_HOLDING_REGISTERS, cst.READ_COILS, cst.WRITE_SINGLE_REGISTER, cst.WRITE_SINGLE_COIL)
|
||||
# self.master.execute(1, cst.WRITE_MULTIPLE_REGISTERS, 0, output_value=[1, 2, 3, 4, 5])
|
||||
# self.master.execute(1, cst.WRITE_MULTIPLE_REGISTERS, starting_address=5, output_value=[3.0], data_format='>f')
|
||||
# self.master.execute(1, cst.WRITE_MULTIPLE_REGISTERS, starting_address=6, output_value=[4.0], data_format='>f')
|
||||
# self.master.execute(2, cst.WRITE_SINGLE_COIL, 2, output_value=1)
|
||||
# self.master.execute(2, cst.WRITE_MULTIPLE_COILS, 0, output_value=[1, 1, 0, 1, 1, 0, 1, 1])
|
||||
# logger.info(master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 2, data_format='f'))
|
||||
|
||||
# Read and write floats
|
||||
|
||||
# send some queries
|
||||
# logger.info(master.execute(1, cst.READ_HOLDING_REGISTERS, 100, 12))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
tcpMaster = TcpMaster('127.0.0.1', 502)
|
||||
a = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,1]
|
||||
tcpMaster.writeSingleRegister(1, 0, a)
|
||||
# tcpMaster.readHoldingRegisters(1, 6, 2)
|
||||
# tcpMaster.master.execute(1, cst.WRITE_MULTIPLE_REGISTERS, starting_address=0, output_value=[1,2,3,4,5])
|
||||
#
|
||||
# master = modbus_tcp.TcpMaster(host="localhost", port=502)
|
||||
# values = [6]
|
||||
# master.execute(1, cst.WRITE_MULTIPLE_REGISTERS, starting_address=0, output_value=values)
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,29 @@
|
||||
from peewee import *
|
||||
|
||||
client_proxy = Proxy()
|
||||
|
||||
|
||||
class BaseModel(Model):
|
||||
class Meta:
|
||||
database = client_proxy
|
||||
|
||||
@classmethod
|
||||
def update_obj(cls, obj):
|
||||
obj.save()
|
||||
|
||||
@classmethod
|
||||
def delete_obj(cls, id):
|
||||
cls.get(cls.id == id).delete_instance()
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_all(cls):
|
||||
try:
|
||||
return cls.select()
|
||||
except:
|
||||
return 'Error'
|
||||
|
||||
@classmethod
|
||||
def get_by_id(cls, id):
|
||||
return cls.get(cls.id == id)
|
||||
|
@ -0,0 +1,70 @@
|
||||
import sys
|
||||
import os
|
||||
import datetime
|
||||
from peewee import *
|
||||
import json
|
||||
|
||||
from utils.DBModels.BaseModel import BaseModel
|
||||
|
||||
sys.path.append('../')
|
||||
sys.path.append('../../../')
|
||||
|
||||
|
||||
|
||||
|
||||
class DeviceDB(BaseModel):
|
||||
deviceName = CharField()
|
||||
proType = CharField()
|
||||
masterSlaveModel = CharField()
|
||||
areaJson = CharField()
|
||||
pvUpperLimit = CharField()
|
||||
pvLowerLimit = CharField()
|
||||
pvUnit = CharField()
|
||||
createTime = CharField()
|
||||
|
||||
# 查询设备是否存在
|
||||
@classmethod
|
||||
def getByName(cls, deviceName):
|
||||
try:
|
||||
return cls.get(cls.deviceName == str(deviceName))
|
||||
except Exception as e:
|
||||
return print(e)
|
||||
|
||||
|
||||
# 删除设备
|
||||
@classmethod
|
||||
def deleteDevice(cls, deviceName):
|
||||
try:
|
||||
query = cls.delete().where(cls.deviceName == deviceName)
|
||||
query.execute()
|
||||
return 'ok'
|
||||
except Exception as e:
|
||||
return e
|
||||
|
||||
# 添加设备
|
||||
def addDevice(self, deviceName, proType, masterSlaveModel=masterSlaveModel, areaJson=None, pvLowerLimit=pvLowerLimit, pvUpperLimit=pvUpperLimit, pvUnit=pvUnit):
|
||||
self.deviceName = deviceName
|
||||
self.proType = proType
|
||||
self.masterSlaveModel = masterSlaveModel
|
||||
self.areaJson = areaJson
|
||||
self.pvUpperLimit = pvUpperLimit
|
||||
self.pvLowerLimit = pvLowerLimit
|
||||
self.pvUnit = pvUnit
|
||||
self.createTime = datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d %H:%M:%S')
|
||||
# print(self.createTime)
|
||||
self.save()
|
||||
|
||||
def initDevice(self, deviceName, proType, masterSlaveModel, areaJson, pvLowerLimit, pvUpperLimit, pvUnit):
|
||||
self.deviceName = deviceName
|
||||
self.proType = proType
|
||||
self.masterSlaveModel = masterSlaveModel
|
||||
self.areaJson = areaJson
|
||||
self.pvUpperLimit = pvUpperLimit
|
||||
self.pvLowerLimit = pvLowerLimit
|
||||
self.pvUnit = pvUnit
|
||||
self.createTime = datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d %H:%M:%S')
|
||||
self.save()
|
||||
|
||||
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue