TG-PlatformPlus/influxDB.py

308 lines
9.7 KiB
Python

#!/opt/homebrew/bin/python3
# -*- coding:utf-8 -*-
import os, subprocess, psutil
from influxdb_client import InfluxDBClient, Point
from influxdb_client.client.write_api import SYNCHRONOUS
from grafana import grafana
import threading
import json
from logs import log
class InfluxDB():
def __init__(self):
self.reset()
def setConfig(self, conf):
self.username = 'username' in conf and conf['username'] or ""
self.password = 'password' in conf and conf['password'] or ""
self.host = 'host' in conf and conf['host'] or "127.0.0.1"
self.port = 'port' in conf and conf['port'] or 8086
self.token = 'token' in conf and conf['token'] or ""
print(f'InfluxDB config: {self.token}')
self.org = 'org' in conf and conf['org'] or ""
self.bucketName = 'bucket' in conf and conf['bucket'] or ""
print(f'InfluxDB config: {conf}')
def reset(self):
self.client = None
self.query_api = None
self.write_api = None
self.buckets_api = None
self.influxServerName = 'influxd.exe'
self.influxServerDir = os.path.dirname(__file__)
self.influxServer = os.path.join(self.influxServerDir, self.influxServerName)
def checkInfluxd(self, name):
for p in psutil.process_iter(attrs=['name']):
if p.name() == name:
return p.pid
return None
def wait_for_process(self, process):
stdout, stderr = process.communicate()
# 处理进程的输出
def openService(self):
try:
if self.checkInfluxd(self.influxServerName):
return
process = subprocess.Popen(
self.influxServer,
creationflags=subprocess.CREATE_NO_WINDOW,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL
)
# 创建线程来等待进程完成
thread = threading.Thread(target=self.wait_for_process, args=(process,))
thread.start()
except Exception as e:
log.error(e)
def openClient(self):
try:
if self.token == "":
self.client = InfluxDBClient(
url=f'{self.host}:{self.port}',
username=self.username,
password=self.password,
org=self.org,
timeout=200
)
else:
print("token:", self.token)
self.client = InfluxDBClient(
url=f'{self.host}:{self.port}',
token=self.token,
timeout=200
)
self.query_api = self.client.query_api()
self.write_api = self.client.write_api(write_options=SYNCHRONOUS)
self.buckets_api = self.client.buckets_api()
except Exception as e:
print(e)
def closeService(self):
try:
pid = self.checkInfluxd(self.influxServerName)
if pid:
psutil.Process(pid).terminate()
except Exception as e:
print(e)
def closeClient(self):
try:
if not self.client:
return
if not self.client.ping():
self.client.close()
return
except Exception as e:
print(e)
def open(self):
try:
self.reset()
if self.host == '127.0.0.1' or self.host == 'localhost':
self.openService()
self.openClient()
except Exception as e:
print(e)
self.reset()
def close(self):
try:
if self.host == '127.0.0.1' or self.host == 'localhost':
self.closeService()
self.closeClient()
except Exception as e:
print(e)
self.reset()
def setBucket(self, _bucketName = None):
if not _bucketName:
return
self.bucketName = _bucketName
grafana.setBucket(self.bucketName)
def query(self, q):
d = dict()
try:
if not self.client or not self.query_api or not self.client.ping():
self.open()
tables = self.query_api.query(query=q)
tables = tables.to_json()
d = json.loads(tables)
return d
except Exception as error:
log.error(error)
return None
def write(self, measurement, field = None, value = 0, unit = None):
try:
if not field:
return False
if not self.client or not self.write_api or not self.client.ping():
self.open()
if unit:
_field = f'{field} {unit}'
else:
_field = field
point = Point(measurement).field(_field, value)
return self.write_api.write(bucket=self.bucketName, org=self.org, record=point)
except Exception as error:
log.error(error)
return False
def write_points(self, data_points ):
try:
if len(data_points) <= 0:
return False
if not self.client or not self.write_api or not self.client.ping():
self.open()
self.write_api.write(bucket=self.bucketName, org=self.org, record=data_points)
return True
except Exception as error:
log.error(error)
return False
def writeHistory(self, measurement, field = None, value = 0, time = None, unit = None):
try:
if not field or not time:
return False
if not self.client or not self.write_api or not self.client.ping():
self.open()
if unit:
_field = f'{field} {unit}'
else:
_field = field
point = Point(measurement).field(_field, value).time(time)
self.write_api.write(bucket=self.bucketName, org=self.org, record=point)
return True
except Exception as error:
log.error(error)
return False
def writeFromDict(self, pointDict = None):
try:
if not pointDict:
return False
if not self.client or not self.write_api or not self.client.ping():
self.open()
point = Point.from_dict(pointDict)
self.write_api.write(bucket=self.bucketName, org=self.org, record=point)
return True
except Exception as error:
log.error(error)
return False
def create(self, _bucketName):
try:
if not self.client or not self.buckets_api or not self.client.ping():
self.open()
self.setBucket(_bucketName)
buckets = self.buckets_api.find_buckets().buckets
for bucket in buckets:
if bucket.name == _bucketName:
return False, _bucketName
print("create bucket ", _bucketName)
self.buckets_api.create_bucket(bucket_name=_bucketName, org=self.org)
return True, _bucketName
except Exception as error:
log.error(error)
return False, None
def delete(self, _bucketName):
try:
if not self.client or not self.buckets_api:
log.fatal('client fatal')
return False, None
buckets = self.buckets_api.find_buckets().buckets
for bucket in buckets:
if bucket.name == _bucketName:
self.buckets_api.delete_bucket(bucket)
return True, _bucketName
return False, _bucketName
except Exception as error:
log.error(error)
return False, _bucketName
def queryField(self):
try:
q = f'''
from(bucket: "{self.bucketName}")
|> range(start: 0)
|> group(columns: ["_measurement"])
|> distinct(column: "_field")
'''
result = self.query(q)
if not result:
return True, None
temp = dict()
for r in result:
k = r['_measurement']
v = r['_value']
if k not in temp:
temp.setdefault(k,[])
temp[k].append(v)
return True, temp
except Exception as error:
log.error(error)
return False, None
def queryData(self, json_str):
try:
json_dict = json.loads(json_str)
filter_measurement = f'''r["_measurement"] == "{json_dict['measurement'][0]}"'''
for mea in json_dict['measurement'][1:]:
filter_measurement += f''' or r["_measurement"] == "{mea}"'''
filter_field = f'''r["_field"] == "{json_dict['field'][0]}"'''
for field in json_dict['field'][1:]:
filter_field += f''' or r["_field"] == "{field}"'''
q = f'''
from(bucket: "{self.bucketName}")
|> range(start: {json_dict['start']},stop: {json_dict['stop']})
|> filter(fn: (r) => {filter_measurement})
|> filter(fn: (r) => {filter_field})
|> aggregateWindow(every: 10s, fn: mean, createEmpty: false)
|> yield(name: "mean")
'''
data = self.query(q)
return True, data
except Exception as error:
log.error(error)
return False, None
def run(self):
try:
self.open()
except Exception as e:
log.error( e)
self.reset()
influxdb = InfluxDB()