|
|
|
|
import enum
|
|
|
|
|
import logging
|
|
|
|
|
import re
|
|
|
|
|
import threading
|
|
|
|
|
import typing
|
|
|
|
|
from collections import namedtuple
|
|
|
|
|
from copy import deepcopy
|
|
|
|
|
from dataclasses import dataclass
|
|
|
|
|
from functools import lru_cache
|
|
|
|
|
from logging.handlers import RotatingFileHandler
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
|
|
from peewee import SqliteDatabase
|
|
|
|
|
|
|
|
|
|
from Agreement.FQ.skio import exception
|
|
|
|
|
from Agreement.FQ.skio.define import LOGGER, ProtocolType, T_Val, IVar, SigType, ValType, \
|
|
|
|
|
IDev
|
|
|
|
|
from Agreement.FQ.skio.exception import SkError
|
|
|
|
|
from utils.WorkModels import init_database, PointModel, NetworkConfig
|
|
|
|
|
from Agreement.FQ.skio.protocol.pms import SmPXIDev, SmHSLDev
|
|
|
|
|
from Agreement.FQ.skio.worker.memory import MemCache
|
|
|
|
|
from Agreement.FQ.skio.worker.sample import SampleThread
|
|
|
|
|
|
|
|
|
|
from Agreement.FQ.skio.protocol.txs.dev import TXS_PXI_Dev, TXS_Dev, TxsPy
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SkWorkerState(object):
|
|
|
|
|
"""
|
|
|
|
|
状态机
|
|
|
|
|
"""
|
|
|
|
|
database: typing.Optional[SqliteDatabase]
|
|
|
|
|
path: typing.Optional[Path]
|
|
|
|
|
slots: typing.List['SlotInfo']
|
|
|
|
|
ready: bool
|
|
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
|
self.lock = threading.RLock()
|
|
|
|
|
self.ready = False
|
|
|
|
|
self.slots = []
|
|
|
|
|
self.path = None
|
|
|
|
|
self.database = None
|
|
|
|
|
self.mem = MemCache()
|
|
|
|
|
self.sample = SampleThread(self)
|
|
|
|
|
self.force_flag = {}
|
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
return f'{self.__class__.__name__}(ready={self.ready})'
|
|
|
|
|
|
|
|
|
|
def setup(self, path: Path) -> 'SkWorkerState':
|
|
|
|
|
"""
|
|
|
|
|
setup State from path
|
|
|
|
|
:param path:
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
|
|
|
|
# 1. Path
|
|
|
|
|
for x in ('', 'etc', 'log', 'var', 'tmp'):
|
|
|
|
|
p = path.joinpath(x)
|
|
|
|
|
if not p.exists():
|
|
|
|
|
p.mkdir(parents=True)
|
|
|
|
|
|
|
|
|
|
self.path = path
|
|
|
|
|
|
|
|
|
|
# 2. Logger
|
|
|
|
|
hdlr = RotatingFileHandler(
|
|
|
|
|
filename=path.joinpath('log', 'SkIO.log'),
|
|
|
|
|
maxBytes=1024 * 1024 * 5,
|
|
|
|
|
encoding='utf-8'
|
|
|
|
|
)
|
|
|
|
|
fmt = logging.Formatter(
|
|
|
|
|
'[%(levelname)1.1s %(asctime)s %(module)s:%(lineno)d] %(message)s',
|
|
|
|
|
'%y%m%d %H:%M:%S'
|
|
|
|
|
)
|
|
|
|
|
hdlr.setFormatter(fmt)
|
|
|
|
|
hdlr.setLevel(logging.DEBUG)
|
|
|
|
|
LOGGER.setLevel(logging.DEBUG)
|
|
|
|
|
LOGGER.addHandler(hdlr)
|
|
|
|
|
|
|
|
|
|
# 3. Database
|
|
|
|
|
self.database = SqliteDatabase(path.joinpath('etc', 'SkIO.db'))
|
|
|
|
|
init_database(self.database)
|
|
|
|
|
|
|
|
|
|
# 4. Slot
|
|
|
|
|
self.mem.setup(path)
|
|
|
|
|
self.slots = list(map(register_dev, NetworkConfig.select()))
|
|
|
|
|
# sample thread
|
|
|
|
|
for slot in self.slots:
|
|
|
|
|
self.sample.queue.put(slot)
|
|
|
|
|
|
|
|
|
|
if not self.sample.is_alive():
|
|
|
|
|
self.sample.start()
|
|
|
|
|
self.ready = True
|
|
|
|
|
return self
|
|
|
|
|
|
|
|
|
|
def find(self, name: str, **kwargs) -> IVar:
|
|
|
|
|
if not self.database:
|
|
|
|
|
raise exception.SkError(exception.VAR_NOT_FOUND, name)
|
|
|
|
|
return find_variable(name, **kwargs)
|
|
|
|
|
|
|
|
|
|
def read(self, name: str, *, remote: bool = True, **kwargs) -> T_Val:
|
|
|
|
|
"""
|
|
|
|
|
Read Variable Value
|
|
|
|
|
:param name: SigName
|
|
|
|
|
:param remote: read from remote device if remote else local memory
|
|
|
|
|
:param kwargs:
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
|
|
|
|
try:
|
|
|
|
|
var = self.find(name, **kwargs)
|
|
|
|
|
if not var:
|
|
|
|
|
return
|
|
|
|
|
if remote:
|
|
|
|
|
for si in self.slots:
|
|
|
|
|
if si.slot == var.slot:
|
|
|
|
|
val = si.read(var)
|
|
|
|
|
self.mem.write(var, val)
|
|
|
|
|
return val
|
|
|
|
|
|
|
|
|
|
# return self.mem.read(var)
|
|
|
|
|
return 0
|
|
|
|
|
except exception.SkError as e:
|
|
|
|
|
LOGGER.exception(e)
|
|
|
|
|
raise e
|
|
|
|
|
|
|
|
|
|
def write(self, name, value, *, remote=True, **kwargs):
|
|
|
|
|
"""
|
|
|
|
|
Write Variable Value
|
|
|
|
|
:param name: SigName
|
|
|
|
|
:param value: Value
|
|
|
|
|
:param remote: write to remote device if remote else local memory
|
|
|
|
|
:param kwargs:
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
|
|
|
|
try:
|
|
|
|
|
kwargs.setdefault('proc_val', value)
|
|
|
|
|
var = self.find(name, **kwargs)
|
|
|
|
|
LOGGER.info(
|
|
|
|
|
f'write kwargs={name}, {value}, {remote}, {kwargs}; {var}')
|
|
|
|
|
if not var:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if var.trans_value is not None:
|
|
|
|
|
value = var.trans_value
|
|
|
|
|
print('>>iv.trans_value', value)
|
|
|
|
|
|
|
|
|
|
if remote:
|
|
|
|
|
for si in self.slots:
|
|
|
|
|
if si.slot == var.slot:
|
|
|
|
|
value = si.write(var, value)
|
|
|
|
|
self.mem.write(var, value)
|
|
|
|
|
return value
|
|
|
|
|
|
|
|
|
|
# return self.mem.write(var, value)
|
|
|
|
|
return 0
|
|
|
|
|
except exception.SkError as e:
|
|
|
|
|
LOGGER.exception(e)
|
|
|
|
|
raise e
|
|
|
|
|
|
|
|
|
|
def txsPy(self, path):
|
|
|
|
|
path = self.path.joinpath('var', path)
|
|
|
|
|
print('>>>path ',path)
|
|
|
|
|
if not path.exists():
|
|
|
|
|
raise exception.SkError(msg=f'脚本不存在: {path}')
|
|
|
|
|
|
|
|
|
|
txs = TxsPy.compile(path.read_text('utf-8'))
|
|
|
|
|
txs.execute(self)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass
|
|
|
|
|
class SlotInfo(object):
|
|
|
|
|
class Status(enum.Enum):
|
|
|
|
|
READY = 0
|
|
|
|
|
OFFLINE = 1
|
|
|
|
|
ERROR = 2
|
|
|
|
|
|
|
|
|
|
id: int
|
|
|
|
|
slot: str
|
|
|
|
|
protocol: ProtocolType
|
|
|
|
|
uri: str
|
|
|
|
|
description: str
|
|
|
|
|
status: Status = Status.READY
|
|
|
|
|
|
|
|
|
|
dev: typing.Optional[IDev] = None
|
|
|
|
|
|
|
|
|
|
def read(self, var: IVar) -> T_Val:
|
|
|
|
|
return self.dev.read(var)
|
|
|
|
|
|
|
|
|
|
def write(self, var: IVar, value: T_Val) -> T_Val:
|
|
|
|
|
return self.dev.write(var, value)
|
|
|
|
|
|
|
|
|
|
def fetch(self, state: SkWorkerState):
|
|
|
|
|
try:
|
|
|
|
|
if hasattr(self.dev, 'fetch'):
|
|
|
|
|
self.dev.fetch()
|
|
|
|
|
self.status = self.Status.READY
|
|
|
|
|
except exception.SkError as e:
|
|
|
|
|
if e.errno == exception.NETWORK_ERROR:
|
|
|
|
|
self.status = self.Status.OFFLINE
|
|
|
|
|
else:
|
|
|
|
|
self.status = self.Status.ERROR
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def register_dev(dev: NetworkConfig) -> 'SlotInfo':
|
|
|
|
|
"""
|
|
|
|
|
Creat a `SlotInfo` from `DevModel`
|
|
|
|
|
:param dev:
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
|
|
|
|
protocol = ProtocolType[dev.protocol]
|
|
|
|
|
|
|
|
|
|
si = SlotInfo(
|
|
|
|
|
id=dev.id,
|
|
|
|
|
slot=dev.slot,
|
|
|
|
|
protocol=protocol,
|
|
|
|
|
uri=dev.uri,
|
|
|
|
|
description=dev.description,
|
|
|
|
|
status=SlotInfo.Status.READY
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if protocol == ProtocolType.SMPXI:
|
|
|
|
|
si.dev = SmPXIDev()
|
|
|
|
|
elif protocol == ProtocolType.SMHSL:
|
|
|
|
|
si.dev = SmHSLDev()
|
|
|
|
|
elif protocol == ProtocolType.TXS:
|
|
|
|
|
si.dev = TXS_Dev()
|
|
|
|
|
elif protocol == ProtocolType.TXS_PXI_Dev:
|
|
|
|
|
si.dev = TXS_PXI_Dev()
|
|
|
|
|
si.dev.setup(si.uri)
|
|
|
|
|
return si
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_alias = {
|
|
|
|
|
'START_PXI1': 'TSD',
|
|
|
|
|
'START_PXI2': 'TSD',
|
|
|
|
|
'START_PXI3': 'TSD',
|
|
|
|
|
'START_PXI4': 'TSD',
|
|
|
|
|
'START_PXI5': 'TSD',
|
|
|
|
|
'START_PXI6': 'TSD',
|
|
|
|
|
|
|
|
|
|
'52 UV A1': 'PMS-JD-RTSA01-UV',
|
|
|
|
|
'52 Shunt A1': 'PMS-JD-RTSA02-UV',
|
|
|
|
|
'52 UV A2': 'PMS-JD-RTSA01-ST',
|
|
|
|
|
'52 Shunt A2': 'PMS-JD-RTSA02-ST',
|
|
|
|
|
|
|
|
|
|
'52 UV B1': 'PMS-JD-RTSB01-UV',
|
|
|
|
|
'52 Shunt B1': 'PMS-JD-RTSB02-UV',
|
|
|
|
|
'52 UV B2': 'PMS-JD-RTSB01-ST',
|
|
|
|
|
'52 Shunt B2': 'PMS-JD-RTSB02-ST',
|
|
|
|
|
|
|
|
|
|
'52 UV C1': 'PMS-JD-RTSC01-UV',
|
|
|
|
|
'52 Shunt C1': 'PMS-JD-RTSC02-UV',
|
|
|
|
|
'52 UV C2': 'PMS-JD-RTSC01-ST',
|
|
|
|
|
'52 Shunt C2': 'PMS-JD-RTSC02-ST',
|
|
|
|
|
|
|
|
|
|
'52 UV D1': 'PMS-JD-RTSD01-UV',
|
|
|
|
|
'52 Shunt D1': 'PMS-JD-RTSD02-UV',
|
|
|
|
|
'52 UV D2': 'PMS-JD-RTSD01-ST',
|
|
|
|
|
'52 Shunt D2': 'PMS-JD-RTSD02-ST',
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# @lru_cache(maxsize=1024)
|
|
|
|
|
def find_variable(name: str, **kwargs) -> IVar:
|
|
|
|
|
"""
|
|
|
|
|
查找变量信息
|
|
|
|
|
:param name:
|
|
|
|
|
:param kwargs:
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
|
|
|
|
# 福清项目SYS不特殊处理
|
|
|
|
|
# if name.startswith('__SYS.'):
|
|
|
|
|
# LOGGER.info(f'SYS VAR {name}')
|
|
|
|
|
# tag = name.split('.')
|
|
|
|
|
# # 触发边沿
|
|
|
|
|
# if tag[1] == 'EDG':
|
|
|
|
|
# ch = tag[2]
|
|
|
|
|
# if not ch:
|
|
|
|
|
# return
|
|
|
|
|
# ch = int(ch.lstrip('T')) - 1
|
|
|
|
|
# iv = find_variable('EDG')
|
|
|
|
|
# niv = deepcopy(iv)
|
|
|
|
|
# niv.name = f'{iv.name}.{ch}'
|
|
|
|
|
# niv.length = 1
|
|
|
|
|
# fc, addr, size = iv.uri.split(':')
|
|
|
|
|
# niv.uri = f'{fc}:{int(addr)+ch}:{1}'
|
|
|
|
|
# return niv
|
|
|
|
|
|
|
|
|
|
# 新的执行需求
|
|
|
|
|
dd = AnalysisDev(name, **kwargs)
|
|
|
|
|
res = dd.parse_val()
|
|
|
|
|
|
|
|
|
|
if res:
|
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
if name in _alias:
|
|
|
|
|
return find_variable(_alias[name], **kwargs)
|
|
|
|
|
|
|
|
|
|
model: PointModel = PointModel.filter(PointModel.sig_name == name).first()
|
|
|
|
|
|
|
|
|
|
if not model:
|
|
|
|
|
raise exception.SkError(exception.VAR_NOT_FOUND, name)
|
|
|
|
|
|
|
|
|
|
# 数据类型,长度
|
|
|
|
|
if '*' in model.val_type:
|
|
|
|
|
val_type, length = model.val_type.split('*')
|
|
|
|
|
val_type = ValType[val_type.upper()]
|
|
|
|
|
length = int(length)
|
|
|
|
|
else:
|
|
|
|
|
val_type, length = model.val_type, 1
|
|
|
|
|
val_type = ValType[val_type.upper()]
|
|
|
|
|
|
|
|
|
|
# 信号类型
|
|
|
|
|
sig_type = SigType[model.sig_type.upper()]
|
|
|
|
|
|
|
|
|
|
iv = IVar(
|
|
|
|
|
id=model.id,
|
|
|
|
|
name=model.sig_name,
|
|
|
|
|
sig_type=sig_type,
|
|
|
|
|
val_type=val_type,
|
|
|
|
|
length=length,
|
|
|
|
|
uri=model.uri,
|
|
|
|
|
slot=model.slot
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if model.eu is not None:
|
|
|
|
|
iv.eu = model.eu
|
|
|
|
|
if model.rlo is not None:
|
|
|
|
|
iv.rlo = float(model.rlo)
|
|
|
|
|
if model.rhi is not None:
|
|
|
|
|
iv.rhi = float(model.rhi)
|
|
|
|
|
if model.elo is not None:
|
|
|
|
|
iv.elo = float(model.elo)
|
|
|
|
|
if model.ehi is not None:
|
|
|
|
|
iv.ehi = float(model.ehi)
|
|
|
|
|
|
|
|
|
|
return iv
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class BaseAnalysis:
|
|
|
|
|
def __init__(self, name, proc_data):
|
|
|
|
|
self.name = name
|
|
|
|
|
self.proc_data = proc_data
|
|
|
|
|
|
|
|
|
|
def analysis(self):
|
|
|
|
|
raise NotImplementedError
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ChAnalysis(BaseAnalysis):
|
|
|
|
|
NUM_PATTERN = re.compile(r"([0-9\.]+)")
|
|
|
|
|
STR_PATTERN = re.compile(r"([a-zA-Z\%]+)")
|
|
|
|
|
|
|
|
|
|
def __init__(self, name, proc_data):
|
|
|
|
|
super().__init__(name, proc_data)
|
|
|
|
|
|
|
|
|
|
def analysis(self):
|
|
|
|
|
# 带ma的
|
|
|
|
|
if 'ma' in self.proc_data.lower():
|
|
|
|
|
res = self.NUM_PATTERN.search(self.proc_data)
|
|
|
|
|
if res:
|
|
|
|
|
val = res.groups()[0]
|
|
|
|
|
|
|
|
|
|
# 他们是A为单位
|
|
|
|
|
return float(val) / 1000
|
|
|
|
|
return None
|
|
|
|
|
else:
|
|
|
|
|
sdt = self.STR_PATTERN.search(self.proc_data)
|
|
|
|
|
# 带任何字符和%的
|
|
|
|
|
if sdt:
|
|
|
|
|
num_sdt = self.NUM_PATTERN.search(self.proc_data)
|
|
|
|
|
if num_sdt:
|
|
|
|
|
num = float(num_sdt.groups()[0])
|
|
|
|
|
return self.transform_ma(num)
|
|
|
|
|
else:
|
|
|
|
|
raise SkError('22', '无法找到num值')
|
|
|
|
|
# 纯数字的
|
|
|
|
|
else:
|
|
|
|
|
return self.transform_ma(self.proc_data)
|
|
|
|
|
|
|
|
|
|
def read_db(self):
|
|
|
|
|
res = PointModel.filter(PointModel.sig_name == self.name)
|
|
|
|
|
|
|
|
|
|
if len(res) == 0:
|
|
|
|
|
raise ValueError('未找到signame数据')
|
|
|
|
|
elif len(res) > 1:
|
|
|
|
|
raise ValueError('找到多条signame数据')
|
|
|
|
|
else:
|
|
|
|
|
data = res.first()
|
|
|
|
|
return data
|
|
|
|
|
|
|
|
|
|
def transform_ma(self, x3):
|
|
|
|
|
sig_data = self.read_db()
|
|
|
|
|
y3 = ChAnalysis.transform(sig_data, x3)
|
|
|
|
|
|
|
|
|
|
return y3
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def linear_two_unknown(x1, y1, x2, y2, x3):
|
|
|
|
|
"""
|
|
|
|
|
y = ax+b
|
|
|
|
|
:param x1:
|
|
|
|
|
:param y1:
|
|
|
|
|
:param x2:
|
|
|
|
|
:param y2:
|
|
|
|
|
:param x3:
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
|
|
|
|
if (not all((x2, y1, y2))) or (x1 is None):
|
|
|
|
|
return x3
|
|
|
|
|
|
|
|
|
|
a = float((y1 - y2) / (x1 - x2))
|
|
|
|
|
b = float(y1 - (a * x1))
|
|
|
|
|
x3 = float(x3)
|
|
|
|
|
|
|
|
|
|
y3 = a * x3 + b
|
|
|
|
|
# 他们单位 A 我们输入的是ma
|
|
|
|
|
return y3 / 1000
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def times_two_unknown(x1, y1, x2, y2, x3):
|
|
|
|
|
"""
|
|
|
|
|
y = ax^2 + b
|
|
|
|
|
:param x1:
|
|
|
|
|
:param y1:
|
|
|
|
|
:param x2:
|
|
|
|
|
:param y2:
|
|
|
|
|
:param x3:
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
|
|
|
|
if (not all((x2, y1, y2))) or (x1 is None):
|
|
|
|
|
return x3
|
|
|
|
|
|
|
|
|
|
a = float((y1 - y2) / ((x1 * x1) - (x2 * x2)))
|
|
|
|
|
b = float(y1 - (a * x1 * x1))
|
|
|
|
|
x3 = float(x3)
|
|
|
|
|
|
|
|
|
|
y3 = a * x3 * x3 + b
|
|
|
|
|
# 他们单位 A 我们输入的是ma
|
|
|
|
|
return y3 / 1000
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def transform(varObj, x3: str) -> float:
|
|
|
|
|
if varObj.initial == 1:
|
|
|
|
|
y3 = ChAnalysis.times_two_unknown(
|
|
|
|
|
varObj.rlo, varObj.elo,
|
|
|
|
|
varObj.rhi, varObj.ehi,
|
|
|
|
|
x3
|
|
|
|
|
)
|
|
|
|
|
else:
|
|
|
|
|
y3 = ChAnalysis.linear_two_unknown(
|
|
|
|
|
varObj.rlo, varObj.elo,
|
|
|
|
|
varObj.rhi, varObj.ehi,
|
|
|
|
|
x3
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
return y3
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TxAnalysis(BaseAnalysis):
|
|
|
|
|
TX_DATA = namedtuple('TX_DATA', (
|
|
|
|
|
'signame_first',
|
|
|
|
|
'signame_second',
|
|
|
|
|
'signame_third',
|
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
def __init__(self, name, proc_data):
|
|
|
|
|
super().__init__(name, proc_data)
|
|
|
|
|
|
|
|
|
|
def read_tx_data(self):
|
|
|
|
|
res = self.name.split('.')
|
|
|
|
|
if len(res) == 3:
|
|
|
|
|
tx_data = self.TX_DATA(
|
|
|
|
|
signame_first=res[0],
|
|
|
|
|
signame_second=res[1],
|
|
|
|
|
signame_third=res[2]
|
|
|
|
|
)
|
|
|
|
|
elif len(res) == 1:
|
|
|
|
|
tx_data = self.TX_DATA(
|
|
|
|
|
signame_first=res[0],
|
|
|
|
|
signame_second=None,
|
|
|
|
|
signame_third=None
|
|
|
|
|
)
|
|
|
|
|
else:
|
|
|
|
|
second_data = res[1]
|
|
|
|
|
if second_data.lower() in ('m1', 'm2'):
|
|
|
|
|
tx_data = self.TX_DATA(
|
|
|
|
|
signame_first=res[0],
|
|
|
|
|
signame_second=None,
|
|
|
|
|
signame_third=second_data
|
|
|
|
|
)
|
|
|
|
|
else:
|
|
|
|
|
tx_data = self.TX_DATA(
|
|
|
|
|
signame_first=res[0],
|
|
|
|
|
signame_second=second_data,
|
|
|
|
|
signame_third=None
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
return tx_data
|
|
|
|
|
|
|
|
|
|
def analysis(self):
|
|
|
|
|
self.tx_data = self.read_tx_data()
|
|
|
|
|
data = self.parse_data(self.tx_data)
|
|
|
|
|
return data
|
|
|
|
|
|
|
|
|
|
def parse_data(self, tx_data):
|
|
|
|
|
"""
|
|
|
|
|
#todo 对tx_data进行query搜索,根据第一个,第二个和第三个值做对应的搜索
|
|
|
|
|
:param tx_data:
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
tx_keyword = tx_data.signame_first
|
|
|
|
|
if tx_data.signame_second:
|
|
|
|
|
tx_keyword += '.' + tx_data.signame_second
|
|
|
|
|
|
|
|
|
|
res = None
|
|
|
|
|
if tx_data.signame_third:
|
|
|
|
|
if tx_data.signame_third == 'M1':
|
|
|
|
|
res = PointModel.filter((PointModel.sig_name.contains(tx_keyword)) & (VarModel.channel == 'M1'))
|
|
|
|
|
elif tx_data.signame_third == 'M2':
|
|
|
|
|
res = PointModel.filter(PointModel.sig_name.contains(tx_keyword))
|
|
|
|
|
else:
|
|
|
|
|
res = PointModel.filter(PointModel.sig_name.contains(tx_keyword))
|
|
|
|
|
|
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
def data_to_ivar(self):
|
|
|
|
|
res = self.parse_data(self.read_tx_data())
|
|
|
|
|
self.ivar_list = []
|
|
|
|
|
for dt in res:
|
|
|
|
|
|
|
|
|
|
# 数据类型,长度
|
|
|
|
|
if '*' in dt.val_type:
|
|
|
|
|
val_type, length = dt.val_type.split('*')
|
|
|
|
|
val_type = ValType[val_type.upper()]
|
|
|
|
|
length = int(length)
|
|
|
|
|
else:
|
|
|
|
|
val_type, length = dt.val_type, 1
|
|
|
|
|
val_type = ValType[val_type.upper()]
|
|
|
|
|
|
|
|
|
|
# 信号类型
|
|
|
|
|
sig_type = SigType[dt.sig_type.upper()]
|
|
|
|
|
|
|
|
|
|
iv = IVar(
|
|
|
|
|
id=dt.id,
|
|
|
|
|
name=dt.sig_name,
|
|
|
|
|
sig_type=sig_type,
|
|
|
|
|
val_type=val_type,
|
|
|
|
|
length=1,
|
|
|
|
|
uri=dt.uri,
|
|
|
|
|
slot=dt.slot,
|
|
|
|
|
channel=dt.channel
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if dt.eu is not None:
|
|
|
|
|
iv.eu = dt.eu
|
|
|
|
|
if dt.rlo is not None:
|
|
|
|
|
iv.rlo = float(dt.rlo)
|
|
|
|
|
if dt.rhi is not None:
|
|
|
|
|
iv.rhi = float(dt.rhi)
|
|
|
|
|
if dt.elo is not None:
|
|
|
|
|
iv.elo = float(dt.elo)
|
|
|
|
|
if dt.ehi is not None:
|
|
|
|
|
iv.ehi = float(dt.ehi)
|
|
|
|
|
|
|
|
|
|
self.ivar_list.append(iv)
|
|
|
|
|
|
|
|
|
|
return self.ivar_list
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class AnalysisDev:
|
|
|
|
|
"""
|
|
|
|
|
ad1 = AnalysisDev('XRPB201SM1.M2', proc_val='1(TX)', trigger=1)
|
|
|
|
|
ad1.parse_val()
|
|
|
|
|
"""
|
|
|
|
|
VAL_PATTERN = re.compile(r"([a-zA-Z0-9\-\.\%\/]+)\(([a-zA-Z0-9\-]+)\)")
|
|
|
|
|
TX_PATTENR = re.compile(r"([0-9\.\-]+)")
|
|
|
|
|
|
|
|
|
|
def __init__(self, name, **kwargs):
|
|
|
|
|
self.name = name
|
|
|
|
|
self.proc_val = kwargs.get('proc_val')
|
|
|
|
|
self.trigger = kwargs.get('trigger')
|
|
|
|
|
self.need_time = kwargs.get('need_time')
|
|
|
|
|
|
|
|
|
|
# txs_port 调用port接口
|
|
|
|
|
self.txs_port = kwargs.get('txs_port')
|
|
|
|
|
# print(self.txs_port)
|
|
|
|
|
|
|
|
|
|
MAGIC_NUMBER = 5
|
|
|
|
|
|
|
|
|
|
def parse_val(self) -> (IVar, float):
|
|
|
|
|
if not self.proc_val:
|
|
|
|
|
return None
|
|
|
|
|
res = self.VAL_PATTERN.search(self.proc_val)
|
|
|
|
|
if not res:
|
|
|
|
|
return
|
|
|
|
|
proc_data, proc_type = res.groups()
|
|
|
|
|
|
|
|
|
|
if 'ch' in proc_type.lower():
|
|
|
|
|
# print('++++ channel', self.name)
|
|
|
|
|
if self.name[0].upper() == 'X':
|
|
|
|
|
self.name = f'{self.MAGIC_NUMBER}{self.name[1:]}'
|
|
|
|
|
ana = ChAnalysis(self.name, proc_data)
|
|
|
|
|
res = ana.read_db()
|
|
|
|
|
self.value = ana.analysis()
|
|
|
|
|
|
|
|
|
|
ch = proc_type[2:]
|
|
|
|
|
elif 'tx' in proc_type.lower():
|
|
|
|
|
ana = TxAnalysis(self.name, proc_data)
|
|
|
|
|
# res = ana.analysis()
|
|
|
|
|
res = ana.data_to_ivar()
|
|
|
|
|
|
|
|
|
|
# tx的value读取整数
|
|
|
|
|
gps = self.TX_PATTENR.search(self.proc_val)
|
|
|
|
|
if not gps:
|
|
|
|
|
raise SkError(22, '无法匹配到数值')
|
|
|
|
|
else:
|
|
|
|
|
self.value = float(gps.groups()[0])
|
|
|
|
|
else:
|
|
|
|
|
self.value = None
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if isinstance(res, PointModel):
|
|
|
|
|
iv = IVar(
|
|
|
|
|
id=res.id,
|
|
|
|
|
name=res.sig_name,
|
|
|
|
|
sig_type=res.sig_type,
|
|
|
|
|
val_type=res.val_type,
|
|
|
|
|
length=1,
|
|
|
|
|
uri=res.uri,
|
|
|
|
|
slot=res.slot
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if res.eu is not None:
|
|
|
|
|
iv.eu = res.eu
|
|
|
|
|
if res.rlo is not None:
|
|
|
|
|
iv.rlo = float(res.rlo)
|
|
|
|
|
if res.rhi is not None:
|
|
|
|
|
iv.rhi = float(res.rhi)
|
|
|
|
|
if res.elo is not None:
|
|
|
|
|
iv.elo = float(res.elo)
|
|
|
|
|
if res.ehi is not None:
|
|
|
|
|
iv.ehi = float(res.ehi)
|
|
|
|
|
|
|
|
|
|
iv.trigger = self.trigger
|
|
|
|
|
iv.channel = ch
|
|
|
|
|
|
|
|
|
|
if self.txs_port:
|
|
|
|
|
iv.txs_port = self.txs_port
|
|
|
|
|
else:
|
|
|
|
|
print(res)
|
|
|
|
|
iv = IVar(
|
|
|
|
|
id=res[0].id,
|
|
|
|
|
name=self.name,
|
|
|
|
|
sig_type=SigType.TXS,
|
|
|
|
|
length=1,
|
|
|
|
|
slot=res[0].slot,
|
|
|
|
|
val_type=ValType.D64
|
|
|
|
|
)
|
|
|
|
|
iv.trigger = self.trigger
|
|
|
|
|
iv.group = res
|
|
|
|
|
print(iv.group)
|
|
|
|
|
|
|
|
|
|
iv.trans_value = self.value
|
|
|
|
|
|
|
|
|
|
if self.need_time:
|
|
|
|
|
iv.need_time = self.need_time
|
|
|
|
|
|
|
|
|
|
if self.txs_port:
|
|
|
|
|
iv.txs_port = self.txs_port
|
|
|
|
|
|
|
|
|
|
return iv
|