PCM_Viewer/influxdb_wrapper.py

135 lines
3.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

"""
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()