PCM_Viewer/influxdb_wrapper.py

135 lines
3.8 KiB
Python
Raw Normal View History

2026-02-06 22:49:52 +08:00
"""
InfluxDB 客户端模块
"""
from PyQt6.QtCore import QObject, pyqtSignal as Signal, QTimer, pyqtSlot as Slot
from influxdb_client import InfluxDBClient as InfluxClientLib
from typing import Dict, List, Optional
import logging
logger = logging.getLogger(__name__)
class InfluxDBClient(QObject):
"""
InfluxDB 客户端用于获取实时数据
"""
dataReceived = Signal(dict) # 数据接收信号,参数为 {field_name: value}
errorOccurred = Signal(str) # 错误信号
def __init__(self, parent=None):
super().__init__(parent)
self._client: Optional[InfluxClientLib] = None
self._url: str = ""
self._token: str = ""
self._org: str = ""
self._bucket: str = ""
self._query: str = ""
self._timer: Optional[QTimer] = None
self._is_connected: bool = False
@Slot(str, str, str, str)
def connect(self, url: str, token: str, org: str, bucket: str):
"""连接到 InfluxDB"""
try:
self._url = url
self._token = token
self._org = org
self._bucket = bucket
if self._client:
self._client.close()
self._client = InfluxClientLib(
url=url,
token=token,
org=org
)
# 测试连接
query_api = self._client.query_api()
test_query = f'from(bucket: "{bucket}") |> range(start: -1m) |> limit(n: 1)'
query_api.query(test_query)
self._is_connected = True
logger.info(f"Connected to InfluxDB: {url}")
except Exception as e:
self._is_connected = False
error_msg = f"连接失败: {str(e)}"
logger.error(error_msg)
self.errorOccurred.emit(error_msg)
@Slot(str)
def setQuery(self, query: str):
"""设置查询语句"""
self._query = query
@Slot(int)
def startQuery(self, interval_ms: int = 1000):
"""开始定时查询interval_ms 为毫秒"""
if not self._is_connected:
self.errorOccurred.emit("未连接到 InfluxDB")
return
if self._timer:
self._timer.stop()
self._timer = QTimer(self)
self._timer.timeout.connect(self._executeQuery)
self._timer.start(interval_ms)
# 立即执行一次
self._executeQuery()
@Slot()
def stopQuery(self):
"""停止查询"""
if self._timer:
self._timer.stop()
def _executeQuery(self):
"""执行查询"""
if not self._is_connected or not self._query:
return
try:
query_api = self._client.query_api()
result = query_api.query(self._query)
# 解析查询结果
data = {}
for table in result:
for record in table.records:
field = record.get_field()
value = record.get_value()
# 如果同一个字段有多个值,取最后一个
data[field] = value
if data:
self.dataReceived.emit(data)
except Exception as e:
error_msg = f"查询失败: {str(e)}"
logger.error(error_msg)
self.errorOccurred.emit(error_msg)
@Slot()
def disconnect(self):
"""断开连接"""
if self._timer:
self._timer.stop()
if self._client:
self._client.close()
self._client = None
self._is_connected = False
def __del__(self):
self.disconnect()