0313界面对接

This commit is contained in:
2026-03-13 21:04:19 +08:00
parent 6e74eaf206
commit 8aeaffa885
33 changed files with 1541 additions and 419 deletions

43
common/helpers.py Normal file
View File

@ -0,0 +1,43 @@
"""工具函数模块"""
def get_f_block_positions(artifact_list):
"""获取artifact_list中F块的位置"""
positions = []
for i, artifact in enumerate(artifact_list):
if artifact.get("BlockNumber") == "F":
positions.append(i)
return positions
def cleanup_old_timestamps(artifact_timestamps, current_artifact_ids=None, max_age_hours=24):
"""
清理过期的时间戳记录
Args:
artifact_timestamps: 时间戳字典
current_artifact_ids: 当前活跃的artifact_id集合可选
max_age_hours: 时间戳最大保留时间小时默认24小时
"""
from datetime import datetime
current_time = datetime.now()
expired_ids = []
# 遍历所有存储的时间戳记录
for artifact_id, timestamp in artifact_timestamps.items():
# 如果提供了当前活跃ID列表且该ID不在当前活跃列表中则检查是否过期
if current_artifact_ids is None or artifact_id not in current_artifact_ids:
age = current_time - timestamp
# 如果超过最大保留时间,则标记为过期
if age.total_seconds() > max_age_hours * 3600:
expired_ids.append(artifact_id)
# 删除过期的时间戳记录
for artifact_id in expired_ids:
del artifact_timestamps[artifact_id]
if expired_ids:
print(f"清理了 {len(expired_ids)} 个过期的时间戳记录: {expired_ids}")
return len(expired_ids)

View File

@ -108,14 +108,16 @@ class SQLiteHandler:
"""SQLite数据库操作通用类单例模式"""
_lock = threading.Lock() # 单例锁
_instance = None
_instances = {}
@classmethod
def get_instance(cls, *args, **kwargs):
if cls._instance is None:
def get_instance(cls,db_path, *args, **kwargs):
# 使用文件路径作为键
key = db_path
if key not in cls._instances:
with cls._lock:
if cls._instance is None: # 双重检查
cls._instance = cls(*args, **kwargs)
return cls._instance
if key not in cls._instances: # 双重检查
cls._instances[key] = cls(db_path, *args, **kwargs)
return cls._instances[key]
def __init__(self, db_path: str = "three.db", max_readers: int = 10, busy_timeout: int = 5000):
"""
@ -160,7 +162,7 @@ class SQLiteHandler:
try:
# 创建临时连接来设置参数
conn = sqlite3.connect(self.db_path, **self._connection_params)
# 启用WAL模式Write-Ahead Logging
cursor = conn.execute("PRAGMA journal_mode = WAL")
journal_mode = cursor.fetchone()[0]
@ -184,6 +186,7 @@ class SQLiteHandler:
def _create_connection(self) -> sqlite3.Connection:
"""创建新的数据库连接"""
conn = sqlite3.connect(self.db_path, **self._connection_params)
conn.set_trace_callback(lambda x: print(x))
conn.row_factory = sqlite3.Row
return conn

158
common/util_time.py Normal file
View File

@ -0,0 +1,158 @@
import time
class MyTimer:
@staticmethod
def gMyGetTickCount():
ts = time.time()
return int(ts * 1000) # Convert to milliseconds
# CTon class equivalent in Python
class CTon:
def __init__(self):
#已经经过的时间
self.m_unET = 0
#上一次的输入状态(布尔值)
self.m_bLastI = False
#当前的输入状态(布尔值)
self.m_bIn = False
#暂停状态(布尔值)
self.m_bPause = False
#完成状态(布尔值)
self.m_bOver = True
#预设时间(延时时间,毫秒)
self.m_unPT = 0
#开始时间戳(毫秒)
self.m_unStartTime = 0
#暂停时已经经过的时间(毫秒)
self.m_unPauseET = 0
def GetET(self):
if self.m_bIn:
nET = self.m_unPT + (self.m_unStartTime - MyTimer.gMyGetTickCount())
return max(nET, 0)
else:
return 0
def SetReset(self):
self.m_bIn = False
self.m_bLastI = False
self.m_bPause = False
def SetPause(self, value):
if self.m_bIn:
self.m_bPause = value
if self.m_bPause:
self.m_unPauseET = MyTimer.gMyGetTickCount() - self.m_unStartTime
def SetOver(self, value):
self.m_bOver = value
def GetStartTime(self):
return self.m_unStartTime
"""
CTon.Q() 方法实现了一个 通电延时定时器 ,其工作原理如下:
1. 启动 :当输入信号 value_i 变为 True 时,记录当前时间作为开始时间
2. 计时 :从开始时间开始,累计经过的时间
3. 完成 :当经过的时间达到预设时间 value_pt 时,输出变为 True
4. 重置 :当输入信号变为 False 时,定时器重置,输出变为 False
5. 暂停/恢复 :支持暂停功能,暂停后恢复时从暂停点继续计时
"""
def Q(self, value_i, value_pt):
self.m_bIn = value_i
self.m_unPT = value_pt
un_tick = MyTimer.gMyGetTickCount()
if self.m_bOver and self.m_bIn:
self.m_unStartTime = un_tick - self.m_unPT
self.m_bOver = False
if self.m_bPause and self.m_bIn:
self.m_unStartTime = un_tick - self.m_unPauseET
if self.m_bIn != self.m_bLastI:
self.m_bLastI = self.m_bIn
if self.m_bIn:
self.m_unStartTime = un_tick
self.m_bPause = False
return self.m_bIn and (un_tick >= (self.m_unStartTime + self.m_unPT))
# CClockPulse class equivalent in Python
class CClockPulse:
def __init__(self):
self.m_bFirstOut = True
self.m_bTonAOut = False
self.m_bTonBOut = False
self.m_cTonA = CTon()
self.m_cTonB = CTon()
def Q(self, value_i, run_time, stop_time):
if self.m_bFirstOut:
self.m_bTonAOut = self.m_cTonA.Q(not self.m_bTonBOut and value_i, run_time)
self.m_bTonBOut = self.m_cTonB.Q(self.m_bTonAOut and value_i, stop_time)
return not self.m_bTonAOut and value_i
else:
self.m_bTonAOut = self.m_cTonA.Q(not self.m_bTonBOut and value_i, stop_time)
self.m_bTonBOut = self.m_cTonB.Q(self.m_bTonAOut and value_i, run_time)
return self.m_bTonAOut and value_i
# CDelayOut class equivalent in Python
class CDelayOut:
def __init__(self):
self.m_cOutTon = CTon()
self.m_cmWaitTon = CTon()
def Reset(self):
self.m_cOutTon.SetReset()
self.m_cmWaitTon.SetReset()
def Q(self, value_i, wait_time, out_time):
if self.m_cmWaitTon.Q(value_i, wait_time):
if self.m_cOutTon.Q(True, out_time):
self.m_cOutTon.SetReset()
self.m_cmWaitTon.SetReset()
value_i = False
return False
return True
return False
# CRisOrFall class equivalent in Python
class CRisOrFall:
def __init__(self):
self.m_bTemp = False
def Q(self, value_i, ris_or_fall):
result = False
if value_i != self.m_bTemp:
if ris_or_fall and value_i: # Rising edge
result = True
if not ris_or_fall and not value_i: # Falling edge
result = True
self.m_bTemp = value_i
return result
# CTof class equivalent in Python
class CTof:
def __init__(self):
self.m_cDelayTon = CTon()
self.m_bValue = False
self.m_cRis = CRisOrFall()
def SetReset(self):
self.m_bValue = False
self.m_cDelayTon.SetReset()
def Q(self, value_i, delay_time):
if self.m_cRis.Q(value_i, False):
self.m_cDelayTon.SetReset()
self.m_bValue = True
if self.m_cDelayTon.Q(self.m_bValue, delay_time):
self.m_bValue = False
self.m_cDelayTon.SetReset()
return value_i or self.m_bValue
# Utility function
def gGetNowTime():
return int(time.time())