|
|
|
@ -43,12 +43,12 @@ class ProtocolManage(object):
|
|
|
|
self.historyDBManage = Globals.getValue('historyDBManage')
|
|
|
|
self.historyDBManage = Globals.getValue('historyDBManage')
|
|
|
|
self.variableValueCache = {} # {varName: value}
|
|
|
|
self.variableValueCache = {} # {varName: value}
|
|
|
|
self.profibusManager = None
|
|
|
|
self.profibusManager = None
|
|
|
|
self.profibusVarMap = {}
|
|
|
|
|
|
|
|
self.profibusDeviceMeta = {}
|
|
|
|
self.profibusDeviceMeta = {}
|
|
|
|
self.profibusEnabled = GlobalConfigManager.isModuleEnabled('profibusModule')
|
|
|
|
self.profibusEnabled = GlobalConfigManager.isModuleEnabled('profibusModule')
|
|
|
|
self._profibusConnected = False
|
|
|
|
self._profibusConnected = False
|
|
|
|
self._profibusLastUpdate = 0
|
|
|
|
self._profibusLastUpdate = 0
|
|
|
|
self.profibusLock = threading.Lock()
|
|
|
|
self.profibusLock = threading.Lock()
|
|
|
|
|
|
|
|
|
|
|
|
if self.profibusEnabled:
|
|
|
|
if self.profibusEnabled:
|
|
|
|
# print('yeyeye')
|
|
|
|
# print('yeyeye')
|
|
|
|
self._initializeProfibusSupport()
|
|
|
|
self._initializeProfibusSupport()
|
|
|
|
@ -102,7 +102,8 @@ class ProtocolManage(object):
|
|
|
|
except Exception as e:
|
|
|
|
except Exception as e:
|
|
|
|
print(f"刷新缓存时出错: {modelClass.__name__}: {e}")
|
|
|
|
print(f"刷新缓存时出错: {modelClass.__name__}: {e}")
|
|
|
|
if self.profibusEnabled and self.profibusManager:
|
|
|
|
if self.profibusEnabled and self.profibusManager:
|
|
|
|
self._refreshProfibusVarCache()
|
|
|
|
self._registerProfibusVariables()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def lookupVariable(self, variableName):
|
|
|
|
def lookupVariable(self, variableName):
|
|
|
|
@ -126,8 +127,13 @@ class ProtocolManage(object):
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.varInfoCache[variableName] = result # 写入缓存
|
|
|
|
self.varInfoCache[variableName] = result # 写入缓存
|
|
|
|
return result
|
|
|
|
return result
|
|
|
|
|
|
|
|
if self.profibusEnabled and self.profibusManager:
|
|
|
|
|
|
|
|
profibusResult = self._lookupProfibusVariable(variableName)
|
|
|
|
|
|
|
|
if profibusResult:
|
|
|
|
|
|
|
|
return profibusResult
|
|
|
|
return None
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def setClentMode(self, clentName, rabbitmqHost='localhost'):
|
|
|
|
def setClentMode(self, clentName, rabbitmqHost='localhost'):
|
|
|
|
if self.RpcClient:
|
|
|
|
if self.RpcClient:
|
|
|
|
self.RpcClient.close()
|
|
|
|
self.RpcClient.close()
|
|
|
|
@ -254,6 +260,7 @@ class ProtocolManage(object):
|
|
|
|
if not success:
|
|
|
|
if not success:
|
|
|
|
return False
|
|
|
|
return False
|
|
|
|
value = normalizedValue
|
|
|
|
value = normalizedValue
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# HART模拟变量处理
|
|
|
|
# HART模拟变量处理
|
|
|
|
elif modelType == 'HartSimulateVar':
|
|
|
|
elif modelType == 'HartSimulateVar':
|
|
|
|
@ -325,19 +332,19 @@ class ProtocolManage(object):
|
|
|
|
def _initializeProfibusSupport(self):
|
|
|
|
def _initializeProfibusSupport(self):
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
self.profibusManager = DevicesManange()
|
|
|
|
self.profibusManager = DevicesManange()
|
|
|
|
self._loadProfibusDevicesFromDB()
|
|
|
|
self._loadProfibusConfiguration()
|
|
|
|
self.profibusManager.recalculateAddress()
|
|
|
|
self.profibusManager.recalculateAddress()
|
|
|
|
|
|
|
|
self._registerProfibusVariables()
|
|
|
|
except Exception as e:
|
|
|
|
except Exception as e:
|
|
|
|
print(f"初始化PROFIBUS管理器失败: {e}")
|
|
|
|
print(f"初始化PROFIBUS管理器失败: {e}")
|
|
|
|
self.profibusManager = None
|
|
|
|
self.profibusManager = None
|
|
|
|
self.profibusEnabled = False
|
|
|
|
self.profibusEnabled = False
|
|
|
|
|
|
|
|
|
|
|
|
def _loadProfibusDevicesFromDB(self):
|
|
|
|
def _loadProfibusConfiguration(self):
|
|
|
|
self.profibusDeviceMeta = {}
|
|
|
|
self.profibusDeviceMeta = {}
|
|
|
|
allDevices = DevicesManange.getAllDevice()
|
|
|
|
allDevices = DevicesManange.getAllDevice()
|
|
|
|
if not allDevices or isinstance(allDevices, str):
|
|
|
|
if not allDevices or isinstance(allDevices, str):
|
|
|
|
return
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
for deviceRow in allDevices:
|
|
|
|
for deviceRow in allDevices:
|
|
|
|
if not deviceRow:
|
|
|
|
if not deviceRow:
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
@ -365,9 +372,9 @@ class ProtocolManage(object):
|
|
|
|
except Exception as e:
|
|
|
|
except Exception as e:
|
|
|
|
print(f"初始化设备 {deviceName} 失败: {e}")
|
|
|
|
print(f"初始化设备 {deviceName} 失败: {e}")
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
self._loadAreasForDevice(deviceName, areaJson)
|
|
|
|
self._addProfibusAreas(deviceName, areaJson)
|
|
|
|
|
|
|
|
|
|
|
|
def _loadAreasForDevice(self, deviceName, areaJson):
|
|
|
|
def _addProfibusAreas(self, deviceName, areaJson):
|
|
|
|
if not areaJson:
|
|
|
|
if not areaJson:
|
|
|
|
return
|
|
|
|
return
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
@ -403,58 +410,61 @@ class ProtocolManage(object):
|
|
|
|
print(f"添加设备 {deviceName} 的区域 {valueName} 失败: {e}")
|
|
|
|
print(f"添加设备 {deviceName} 的区域 {valueName} 失败: {e}")
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
def _refreshProfibusVarCache(self):
|
|
|
|
def _registerProfibusVariables(self):
|
|
|
|
self.profibusVarMap.clear()
|
|
|
|
if not self.profibusEnabled or not self.profibusManager:
|
|
|
|
if not self.profibusEnabled:
|
|
|
|
|
|
|
|
return
|
|
|
|
return
|
|
|
|
with self.profibusLock:
|
|
|
|
for areaInfo in self._iterProfibusAreas():
|
|
|
|
try:
|
|
|
|
varName = areaInfo.get('valueName')
|
|
|
|
self.profibusManager = DevicesManange()
|
|
|
|
if not varName:
|
|
|
|
self._loadProfibusDevicesFromDB()
|
|
|
|
continue
|
|
|
|
self.profibusManager.recalculateAddress()
|
|
|
|
self.varInfoCache[varName] = {
|
|
|
|
self._profibusConnected = False
|
|
|
|
|
|
|
|
self._profibusLastUpdate = 0
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
|
|
print(f"刷新PROFIBUS设备失败: {e}")
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
deviceGroups = [
|
|
|
|
|
|
|
|
self.profibusManager.dpMasterDevices,
|
|
|
|
|
|
|
|
self.profibusManager.dpSlaveDevices,
|
|
|
|
|
|
|
|
self.profibusManager.paMasterDevices,
|
|
|
|
|
|
|
|
self.profibusManager.paSlaveDevices
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
snapshot = []
|
|
|
|
|
|
|
|
for devicesDict in deviceGroups:
|
|
|
|
|
|
|
|
for deviceName, device in devicesDict.items():
|
|
|
|
|
|
|
|
deviceMeta = self.profibusDeviceMeta.get(deviceName, {})
|
|
|
|
|
|
|
|
for areaIndex, area in enumerate(device.areas):
|
|
|
|
|
|
|
|
valueName = getattr(area, 'valueName', None)
|
|
|
|
|
|
|
|
if not valueName:
|
|
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
areaInfo = {
|
|
|
|
|
|
|
|
'deviceName': deviceName,
|
|
|
|
|
|
|
|
'areaIndex': areaIndex,
|
|
|
|
|
|
|
|
'areaType': area.type,
|
|
|
|
|
|
|
|
'bytes': area.bytes,
|
|
|
|
|
|
|
|
'order': area.order,
|
|
|
|
|
|
|
|
'valueName': valueName,
|
|
|
|
|
|
|
|
'proType': device.type,
|
|
|
|
|
|
|
|
'masterSlaveModel': device.masterOrSlave,
|
|
|
|
|
|
|
|
'min': deviceMeta.get('pvLowerLimit'),
|
|
|
|
|
|
|
|
'max': deviceMeta.get('pvUpperLimit'),
|
|
|
|
|
|
|
|
'unit': deviceMeta.get('pvUnit'),
|
|
|
|
|
|
|
|
'varType': area.type
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
snapshot.append((valueName, areaInfo))
|
|
|
|
|
|
|
|
for valueName, areaInfo in snapshot:
|
|
|
|
|
|
|
|
self.profibusVarMap[valueName] = areaInfo
|
|
|
|
|
|
|
|
self.varInfoCache[valueName] = {
|
|
|
|
|
|
|
|
'modelType': 'ProfibusVar',
|
|
|
|
'modelType': 'ProfibusVar',
|
|
|
|
'variableData': areaInfo
|
|
|
|
'variableData': dict(areaInfo)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _iterProfibusAreas(self):
|
|
|
|
|
|
|
|
if not self.profibusManager:
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
deviceGroups = [
|
|
|
|
|
|
|
|
self.profibusManager.dpMasterDevices,
|
|
|
|
|
|
|
|
self.profibusManager.dpSlaveDevices,
|
|
|
|
|
|
|
|
self.profibusManager.paMasterDevices,
|
|
|
|
|
|
|
|
self.profibusManager.paSlaveDevices
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
for devicesDict in deviceGroups:
|
|
|
|
|
|
|
|
for deviceName, device in devicesDict.items():
|
|
|
|
|
|
|
|
deviceMeta = self.profibusDeviceMeta.get(deviceName, {})
|
|
|
|
|
|
|
|
for areaIndex, area in enumerate(device.areas):
|
|
|
|
|
|
|
|
yield {
|
|
|
|
|
|
|
|
'deviceName': deviceName,
|
|
|
|
|
|
|
|
'areaIndex': areaIndex,
|
|
|
|
|
|
|
|
'areaType': area.type,
|
|
|
|
|
|
|
|
'bytes': getattr(area, 'bytes', 0),
|
|
|
|
|
|
|
|
'order': getattr(area, 'order', 'ABCD'),
|
|
|
|
|
|
|
|
'valueName': getattr(area, 'valueName', None),
|
|
|
|
|
|
|
|
'proType': device.type,
|
|
|
|
|
|
|
|
'masterSlaveModel': device.masterOrSlave,
|
|
|
|
|
|
|
|
'min': deviceMeta.get('pvLowerLimit'),
|
|
|
|
|
|
|
|
'max': deviceMeta.get('pvUpperLimit'),
|
|
|
|
|
|
|
|
'unit': deviceMeta.get('pvUnit'),
|
|
|
|
|
|
|
|
'varType': area.type
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _lookupProfibusVariable(self, variableName):
|
|
|
|
|
|
|
|
if not self.profibusEnabled or not self.profibusManager:
|
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
for areaInfo in self._iterProfibusAreas() or []:
|
|
|
|
|
|
|
|
if areaInfo.get('valueName') == variableName:
|
|
|
|
|
|
|
|
result = {
|
|
|
|
|
|
|
|
'modelType': 'ProfibusVar',
|
|
|
|
|
|
|
|
'variableData': dict(areaInfo)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
self.varInfoCache[variableName] = result
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
def _ensureProfibusConnected(self):
|
|
|
|
def _ensureProfibusConnected(self):
|
|
|
|
|
|
|
|
|
|
|
|
if not self.profibusManager:
|
|
|
|
if not self.profibusManager:
|
|
|
|
return False
|
|
|
|
return False
|
|
|
|
if self._profibusConnected:
|
|
|
|
if self._profibusConnected:
|
|
|
|
@ -637,40 +647,14 @@ class ProtocolManage(object):
|
|
|
|
return False
|
|
|
|
return False
|
|
|
|
return self._ensureProfibusConnected()
|
|
|
|
return self._ensureProfibusConnected()
|
|
|
|
|
|
|
|
|
|
|
|
def refreshProfibusVariables(self):
|
|
|
|
|
|
|
|
if self.profibusEnabled:
|
|
|
|
|
|
|
|
self._refreshProfibusVarCache()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def updateProfibusAreas(self, force: bool = False) -> bool:
|
|
|
|
def updateProfibusAreas(self, force: bool = False) -> bool:
|
|
|
|
if not self.hasProfibusSupport():
|
|
|
|
if not self.hasProfibusSupport():
|
|
|
|
return False
|
|
|
|
return False
|
|
|
|
self._updateProfibusAreas(force=force)
|
|
|
|
self._updateProfibusAreas(force=force)
|
|
|
|
return True
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
def listProfibusVariables(self) -> Dict[str, Dict[str, Any]]:
|
|
|
|
|
|
|
|
return {name: dict(info) for name, info in self.profibusVarMap.items()}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getProfibusVariableInfo(self, variableName: str) -> Optional[Dict[str, Any]]:
|
|
|
|
|
|
|
|
return self.profibusVarMap.get(variableName)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def readProfibusValue(self, variableName: str, useCache: bool = True):
|
|
|
|
|
|
|
|
if not self.hasProfibusSupport():
|
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
if useCache:
|
|
|
|
|
|
|
|
with self.cacheLock:
|
|
|
|
|
|
|
|
if variableName in self.variableValueCache:
|
|
|
|
|
|
|
|
return self.variableValueCache[variableName]
|
|
|
|
|
|
|
|
value = self.readVariableValue(variableName)
|
|
|
|
|
|
|
|
with self.cacheLock:
|
|
|
|
|
|
|
|
self.variableValueCache[variableName] = value
|
|
|
|
|
|
|
|
return value
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def writeProfibusValue(self, variableName: str, value) -> bool:
|
|
|
|
|
|
|
|
if not self.hasProfibusSupport():
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
return bool(self.writeVariableValue(variableName, value))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getAllVariableNames(self):
|
|
|
|
def getAllVariableNames(self):
|
|
|
|
|
|
|
|
|
|
|
|
return list(self.varInfoCache.keys())
|
|
|
|
return list(self.varInfoCache.keys())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|