添加influxdb数据读取接口

iot
DESKTOP-1JS6RSM\Admin 3 months ago
parent f98775a493
commit 194dfcf2a3

@ -2,6 +2,7 @@
[envs.default]
type = "virtual"
dependencies = [
"influxdb-client",
"flask>=3.1.0",
"apiflask>=2.4.0",
"flask-cors>=6.0.0",

@ -1,7 +1,7 @@
FLASK_ENV=dev
SECRET_KEY=iti-flask
JWT_SECRET_KEY=iti-flask
DATABASE_URL=mysql+pymysql://root:root@127.0.0.1:3307/iti-flask?charset=utf8mb4
DATABASE_URL=mysql+pymysql://root:chen222262@124.223.195.237:13306/iti-flask?charset=utf8mb4
# 前端相关
FRONTEND_ENABLED=False # 是否启用前端渲染
FRONTEND_PATH=dist # 前端文件所在位置,若static则无需填写
@ -12,4 +12,12 @@ FRONTEND_PATH=dist # 前端文件所在位置,若static则无需填写
ALIYUN_OSS_ACCESS_KEY_ID=LTAI5t9cymUAWHVEo36yygaT
ALIYUN_OSS_ACCESS_KEY_SECRET=FaaUsxadRYyshbYeAV8ypZNYVOx3tE
ALIYUN_OSS_ENDPOINT=oss-cn-chengdu.aliyuncs.com
ALIYUN_OSS_BUCKET=maintaince-dev
ALIYUN_OSS_BUCKET=maintaince-dev
# ============================================
# influxdb 配置
# ============================================
INFLUXDB_URL="http://124.223.195.237:8086"
INFLUXDB_TOKEN="HdHOox3RqEjJ--Ma9_dFcf-Iv8wu2u0FyD_sV4MT4EIoQoT7h4eZLR_n_yGgmiSLAGiIaUgaH6x-cILNGV8W4g=="
INFLUXDB_ORG="noface"
INFLUXDB_BUCKET="yh-iot"

@ -14,6 +14,7 @@ from iti.applications.common import ModelFilter
from iti.applications.common.exceptions.biz_exp import BizException
from flask_jwt_extended import jwt_required
from sqlalchemy import select, delete, exists
from sqlalchemy.sql.functions import func
from sqlalchemy.orm import noload
from iti.applications.common import permission
@ -104,6 +105,25 @@ def delete_device(id: int):
db.session.commit()
return success()
@bp.get("/count")
@jwt_required()
@bp.doc(security="JWT")
@permission("iot:device:list")
def count_device():
"""
统计设备数量
"""
countData = {}
deviceReady = db.session.query(func.count(IotDevice.id).label('number')).filter_by(status=1).first().number
deviceUnready = db.session.query(func.count(IotDevice.id).label('number')).filter_by(status=0).first().number
deviceFix = db.session.query(func.count(IotDevice.id).label('number')).filter_by(status=2).first().number
countData["ready"] = deviceReady
countData["unReady"] = deviceUnready
countData["fix"] = deviceFix
countData["total"] = deviceReady + deviceUnready + deviceFix
return success(countData)
def get_page(query_data: DeviceQuery):
"""

@ -15,6 +15,7 @@ from iti.applications.common import ModelFilter
from iti.applications.common.exceptions.biz_exp import BizException
from flask_jwt_extended import jwt_required
from sqlalchemy import select, delete, exists
from sqlalchemy.sql.functions import func
from sqlalchemy.orm import noload
from iti.applications.common import permission
@ -115,6 +116,26 @@ def delete_endpoint(id: int):
db.session.commit()
return success()
@bp.get("/count")
@jwt_required()
@bp.doc(security="JWT")
@permission("iot:endpoint:list")
def count_endpoint():
"""
统计采集端数量
"""
countData = {}
endpointReady = db.session.query(func.count(IotEndpoint.id).label('number')).filter_by(status=1).first().number
endpointUnready = db.session.query(func.count(IotEndpoint.id).label('number')).filter_by(status=0).first().number
endpointFix = db.session.query(func.count(IotEndpoint.id).label('number')).filter_by(status=2).first().number
countData["ready"] = endpointReady
countData["unReady"] = endpointUnready
countData["fix"] = endpointFix
countData["total"] = endpointReady + endpointUnready + endpointFix
return success(countData)
def get_page(query_data: EndpointQuery):
"""
获取采集端信息分页

@ -11,6 +11,9 @@ from .schemas.node import (
NodeAddRequest,
NodeUpdateRequest,
)
from iti.applications.service.iot import (
iot_influxdb
)
from iti.applications.common import ModelFilter
from iti.applications.common.exceptions.biz_exp import BizException
from flask_jwt_extended import jwt_required
@ -119,6 +122,34 @@ def delete_node(id: int):
db.session.commit()
return success()
@bp.get("/monitoring/<int:id>")
@jwt_required()
@bp.doc(security="JWT")
@permission("iot:node:list")
def get_node_alert_data(id: int):
"""
获取监控数据
"""
node = db.session.scalar(
select(IotNode)
.options(noload(IotNode.workshop), noload(IotNode.device), noload(IotNode.endpoint))
.filter_by(id=id))
if not node:
raise BizException("采集节点不存在")
measurement = f"ep{node.endpoint_id}_nd{node.id}"
resultData = {}
resultData["title"] = node.title
resultData["dataType"] = node.data_type
resultData["tagLabel"] = node.tag_label
resultData["mark"] = node.mark
resultData["monitoringData"] = iot_influxdb.query_table(measurement, node.tag_label)
return success(resultData)
def get_page(query_data: NodeQuery):
"""

@ -14,6 +14,7 @@ from iti.applications.common import ModelFilter
from iti.applications.common.exceptions.biz_exp import BizException
from flask_jwt_extended import jwt_required
from sqlalchemy import select
from sqlalchemy.sql.functions import func
from iti.applications.common import permission
bp = APIBlueprint("iot_workshop", __name__, url_prefix="/workshop", tag="车间管理")
@ -102,6 +103,24 @@ def delete_workshop(id: int):
db.session.commit()
return success()
@bp.get("/count")
@jwt_required()
@bp.doc(security="JWT")
@permission("iot:workshop:list")
def count_workshop():
"""
统计车间数量
"""
countData = {}
workshopReady = db.session.query(func.count(IotWorkshop.id).label('number')).filter_by(status=1).first().number
workshopUnready = db.session.query(func.count(IotWorkshop.id).label('number')).filter_by(status=0).first().number
countData["ready"] = workshopReady
countData["unReady"] = workshopUnready
countData["total"] = workshopReady + workshopUnready
return success(countData)
def get_list_or_page(query_data: WorkshopQuery):
"""

@ -7,4 +7,7 @@ def init_services(app) -> None:
# 初始化文件目录
from iti.applications.service.sys.sys_file_directory import init_app as init_file_directory
init_file_directory(app)
init_file_directory(app)
from iti.applications.service.iot import init_iot as init_iot_app
init_iot_app(app)

@ -0,0 +1,12 @@
from .influxdb_mgr import iot_influxdb
def init_iot(app) -> None:
import logging
logger = logging.getLogger(__name__)
try:
iot_influxdb.init_app(app)
except Exception as e:
logger.error(f"初始化influxdb_mgr失败: {e}", exc_info=True)

@ -0,0 +1,86 @@
from influxdb_client import InfluxDBClient
from influxdb_client.client.write_api import SYNCHRONOUS
import logging, os
from typing import List, Dict, Any
logger = logging.getLogger(__name__)
class InfluxDBMgr:
"""
influxdb链接管理
"""
_instance = None
_initialized = False
def __new__(cls):
"""
单例模式
"""
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def init_app(self, app):
"""
初始化
"""
if self._initialized:
logger.warning("influxdb连接已初始化跳过重复初始化")
return
logger.info("influxdb初始化...........")
url = os.getenv("INFLUXDB_URL", "")
token = os.getenv("INFLUXDB_TOKEN", "")
org = os.getenv("INFLUXDB_ORG", "")
self.bucket = os.getenv("INFLUXDB_BUCKET", "")
if len(url) == 0:
logger.error("influxdb未配置初始化失败")
self._initialized = False
return
self.client = InfluxDBClient(url=url, token=token, org=org)
def query_table(self, query_measurement: str, query_filed: str)-> List[Dict[str, Any]]:
query_api = self.client.query_api()
flux_query = f'''
from(bucket: "{self.bucket}")
|> range(start: -15m)
|> filter(fn: (r) => r._measurement == "{query_measurement}")
|> filter(fn: (r) => r._field == "{query_filed}")
|> yield(name: "mean")
'''
query_tables = query_api.query(flux_query)
result_records = []
for _table in query_tables:
for record in _table.records:
dict = {}
# record 包含时间、measurement、field、value 和 tags
dict["time"] = record.get_time()
dict["measurement"] = record.get_measurement()
dict["field"] = record.get_field()
dict["value"] = record.get_value()
# dict["tags"] = record.values # 包含所有 tags 和系统字段
# logger.info(f"时间: {time}, measurement: {measurement}, field: {field}, 值: {value}, tags: {tags}")
result_records.append(dict)
return result_records
def close_client(self):
"""
关闭客户端连接释放资源
"""
if hasattr(self, 'client') and self.client:
self.client.close()
logger.info("InfluxDB 客户端已关闭")
def __del__(self):
"""
析构时自动关闭连接有用?
"""
self.close_client()
iot_influxdb = InfluxDBMgr()
Loading…
Cancel
Save