You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

185 lines
7.2 KiB
Python

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import sys
sys.path.append('../../')
import struct
from enum import Enum
from utils.DBModels.DeviceParModels import *
from protocol.ModBus.DPV1Master import DPV1Master
from model.ProjectModel.ParmManage import Parm
import concurrent.futures
import threading
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QThread
class LoadDataThread(QThread):
loadDataSignal = pyqtSignal(int, int)
finished = pyqtSignal(list)
def __init__(self, parent):
super().__init__()
self.parent = parent
def run(self):
valueList = []
for index, parm in enumerate(self.parent.parms):
self.loadDataSignal.emit(len(self.parent.parms), index + 1)
valueList.append(parm.readValue())
self.finished.emit(valueList)
class BlockType(Enum):
TB = 1
PB = 0
FB = 2
class TBType(Enum):
flowTB = -1
tempTB = -2
levelTB = -3 # 物位转换块
pressureTB = -4
class BlockManage():
_instance = None
_dpv1Master = None
def __new__(cls, address):
if not cls._instance:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self, address = None):
self.address = address
if address:
self.initBlocks()
@property
def DPV1Master(self):
if not self._dpv1Master:
self._dpv1Master = DPV1Master('192.168.3.10', 502)
return self._dpv1Master
def initBlocks(self):
if not self.DPV1Master.judgeSlave(self.address):
raise RuntimeError(f"连接从站{self.address}失败.")
self.blockDict = {
BlockType.PB : [],
BlockType.TB : [],
BlockType.FB : [],
}
dirHeadDatas = self.DPV1Master.readParm(address = self.address, slot = 1, index = 0, length = 12)
dirHeadDatas = struct.unpack('>6h', dirHeadDatas)
DirID = dirHeadDatas[0] # 目录id
DirRevNum = dirHeadDatas[1] # 目录版本号
NumDirObj = dirHeadDatas[2] # 目录对象的个数 (如果整个目录使用多于一个目录对象,
# 则这此元素被连续定义,就如同使用一个较大的对象。
# 多个目录对象都被连续地列在该目录中。该对象计数整个目录所需的对象。Header对象不计人其)
NumDirEntry = dirHeadDatas[3] # 目录登录项的总数 (应计算复合列表目录登录项和复合目录登录项的总个数实际块数量为NumDirEntry - 3)
FirstCompListDirEntry = dirHeadDatas[4] # 第1个复合列表目录登录项的目录登录项个数 (该数用来计数目录内的登录项, 而不包含该登
# 录项的参数地址。第1 个目录登录项是在复合列表目录登录项中的物理块引用。在计数登录
# 项时,复合列表目录登录项与复合目录登录项之间无间隔)
NumCompListDirEntry = dirHeadDatas[5] # 功能块类型数量 复合列表目录登录项的个数 计数设备内的不同块类型(物理块、转换块和功能块)和对象类型
#(在本标准范围内仅针对链接对象)
dirLength = 4 * NumDirEntry
dirDatas = self.DPV1Master.readParm(address = self.address, slot = 1, index = 1, length = dirLength)
dirDatas = struct.unpack('>{}h'.format(int(dirLength/2)), dirDatas)
entryTuples = [(dirDatas[i], dirDatas[i+1]) for i in range(0, len(dirDatas), 2)]
for typ in [BlockType.PB, BlockType.TB, BlockType.FB]:
typeIndex = typ.value if type(typ.value) == int else 1
blkDirMesByte = struct.pack('>h', entryTuples[typeIndex][0])
blkIndex = int(blkDirMesByte[0]) # 目录对象编号
blkoffect = int(blkDirMesByte[1]) # 块从第几个Dir_Entry开始
numBlk = entryTuples[typeIndex][1] # 块数量
# print(blkIndex, blkoffect, numBlk)
for i in range(numBlk):
blkEntryListIndex = blkoffect - 1 + i
# print(blkEntryListIndex, entryTuples)
blkPointerByte = struct.pack('>h', entryTuples[blkEntryListIndex][0])
numBlkParms = entryTuples[blkEntryListIndex][1]
blkSlot = int(blkPointerByte[0])
blkStartIndex = int(blkPointerByte[1])
# print(111, blkStartIndex, )
block = Block(typ, self.DPV1Master)
block.slot = blkSlot
block.startIndex = blkStartIndex
block.numParms = numBlkParms
block.blockIndex = i
block.address = self.address
block.addParms()
if not block.getTBType():
self.blockDict[typ].append(block)
# print(blkSlot, blkIndex)
# print(self.blockDict)
def getBlockValues(self, blockType, blockIndex, callback, callback2):
if not isinstance(blockType, BlockType):
typ = BlockType.TB
block = self.blockDict[typ][blockIndex]
block.blockType = blockType
block.addParms()
else:
block = self.blockDict[blockType][blockIndex]
return block.getParmsValue(callback, callback2)
def getBlockNums(self):
return [len(self.blockDict[BlockType.PB]), len(self.blockDict[BlockType.TB]), len(self.blockDict[BlockType.FB])]
@classmethod
def searchSlave(self, callback):
self.DPV1Master.searchSlave(callback)
class Block():
slot = None
startIndex = None
numParms = None
blockIndex = None
address = None
loadDataSignal = pyqtSignal(int, int)
def __init__(self, blockType, DPV1Master):
self.parms = []
self.blockType = blockType
self.DPV1Master = DPV1Master
# self.addParms()
def addParms(self):
self.parms = []
getParmsFunc = {
BlockType.PB: PhysicalBlock.getallParame,
BlockType.TB: PressureTranslationBlock.getallParame,
BlockType.FB: AIFunctionBlock.getallParame,
TBType.flowTB: FlowTranslationBlock.getallParame,
TBType.pressureTB: PressureTranslationBlock.getallParame,
TBType.tempTB: TemperatureTranslationBlock.getallParame,
TBType.levelTB: LevelTranslationBlock.getallParame,
}.get(self.blockType, lambda: [])
parmsData = getParmsFunc()
for parmData in parmsData:
# print(parmData)
# print(self.startIndex, 3214)
parm = Parm(parmData, self.slot, self.startIndex, self)
self.parms.append(parm)
def getParmsValue(self, callback, callback2):
valueList = []
# self.loadDataSignal.connect(callback.loadData)
self.thread = LoadDataThread(self)
self.thread.loadDataSignal.connect(callback)
self.thread.start()
self.thread.finished.connect(callback2)
# thread.join()
# print(valueList)
# return valueList
def getTBType(self):
return
if __name__ == '__main__':
b = BlockManage(address = 55)
c = BlockManage(address = 77)
# b.initBlock()