import sys sys.path.append('../../') import struct from utils.DBModels.DeviceParModels import * from protocol.ModBus.DPV1Master import DPV1Master from model.ProjectModel.ParmManage import Parm class BlockType(Enum): class TB(Enum): phyTB = -1 tempTB = -2 levelTB = -3 # 物位转换块 pressureTB = -4 PB = 0 FB = 1 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 = 66): self.address = 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) 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) 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 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 blkPointerByte = struct.pack('>h', entryTuples[blkEntryListIndex][0]) numBlkParms = entryTuples[blkEntryListIndex][1] blkSlot = int(blkPointerByte[0]) blkStartIndex = int(blkPointerByte[1]) block = Block(typ, self.DPV1Master) block.slot = blkSlot block.startIndex = blkStartIndex block.numParms = numBlkParms block.blockIndex = i block.address = self.address if not block.getTBType(): self.blockDict[typ].append(block) # print(blkSlot, blkIndex) # print(self.blockDict) def getBlockValues(slef, blockType, blockIndex): pass class Block(): slot = None startIndex = None numParms = None blockIndex = None address = None def __init__(self, blockType, DPV1Master): self.parms = [] self.blockType = blockType self.addParms() self.DPV1Master = DPV1Master def addParms(self): getParmsFunc = { BlockType.PB: PhysicalBlock.getallParame, BlockType.TB: AIFunctionBlock.getallParame, BlockType.FB: PressureTranslationBlock.getallParame, }.get(self.blockType, lambda: []) parmsData = getParmsFunc() for parmData in parmsData: parm = Parm(parmData, self.slot, self.startIndex, self.DPV1Master) def getTBType(self): return def setTBType(self): if __name__ == '__main__': b = BlockManage(address = 55) c = BlockManage(address = 77) # b.initBlock()