0313界面对接
This commit is contained in:
43
common/helpers.py
Normal file
43
common/helpers.py
Normal 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)
|
||||
@ -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
158
common/util_time.py
Normal 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())
|
||||
Reference in New Issue
Block a user