forked from iti-framework/iTi-Flask
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
245 lines
7.1 KiB
Python
245 lines
7.1 KiB
Python
from apiflask import APIBlueprint
|
|
from iti.applications.extensions import db, sys_log
|
|
from iti.applications.common.utils import success, page_schema, page
|
|
from iti.applications.models import (
|
|
IotDevice,
|
|
IotEndpoint,
|
|
IotNode,
|
|
IotNodeSchema,
|
|
)
|
|
from .schemas.node import (
|
|
NodeQuery,
|
|
NodeAddRequest,
|
|
NodeUpdateRequest,
|
|
)
|
|
from iti.applications.service.iot import (
|
|
iot_influxdb,
|
|
)
|
|
from iti.applications.service.iot.alert import delete_node_alert_rule
|
|
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
|
|
|
|
|
|
bp = APIBlueprint("iot_node", __name__, url_prefix="/node", tag="采集节点管理")
|
|
|
|
@bp.get("/list")
|
|
@jwt_required()
|
|
@bp.doc(security="JWT")
|
|
@permission("iot:node:list")
|
|
@bp.input(NodeQuery.Schema(partial=True), location="query")
|
|
@bp.output(IotNodeSchema(many=True))
|
|
def list_node(query_data: NodeQuery):
|
|
"""
|
|
获取采集节点列表
|
|
"""
|
|
|
|
return success(get_list(query_data))
|
|
|
|
|
|
@bp.get("/page")
|
|
@jwt_required()
|
|
@bp.doc(security="JWT")
|
|
@permission("iot:node:list")
|
|
@bp.input(NodeQuery.Schema(partial=True), location="query")
|
|
@bp.output(page_schema(IotNodeSchema(many=True)))
|
|
def page_node(query_data: NodeQuery):
|
|
"""
|
|
分页获取采集节点列表
|
|
"""
|
|
|
|
return page(get_page(query_data))
|
|
|
|
@bp.get("/count")
|
|
@jwt_required()
|
|
@bp.doc(security="JWT")
|
|
@permission("iot:node:list")
|
|
def count_node():
|
|
"""
|
|
统计采集节点数量
|
|
"""
|
|
|
|
countData = {}
|
|
nodeReady = db.session.query(func.count(IotNode.id).label('number')).filter_by(status=1).first().number
|
|
nodeUnready = db.session.query(func.count(IotNode.id).label('number')).filter_by(status=0).first().number
|
|
countData["ready"] = nodeReady
|
|
countData["unReady"] = nodeUnready
|
|
countData["total"] = nodeReady + nodeUnready
|
|
|
|
return success(countData)
|
|
|
|
@bp.post("/add")
|
|
@jwt_required()
|
|
@bp.doc(security="JWT")
|
|
@permission("iot:node:add")
|
|
@bp.input(NodeAddRequest, location="json")
|
|
def add_node(json_data: dict):
|
|
"""
|
|
添加采集节点信息
|
|
"""
|
|
|
|
node = IotNode(**json_data)
|
|
endpoint = db.session.scalar(
|
|
select(IotEndpoint)
|
|
.filter_by(id=node.endpoint_id))
|
|
if not endpoint:
|
|
raise BizException("采集端信息不存在")
|
|
device = db.session.scalar(
|
|
select(IotDevice)
|
|
.options(noload(IotDevice.workshop))
|
|
.filter_by(id=node.device_id))
|
|
if not device:
|
|
raise BizException("设备信息不存在")
|
|
|
|
# 判断节点编号是否唯一
|
|
if json_data.get("node_number") is not None:
|
|
if db.session.scalar(
|
|
select(
|
|
exists().where(
|
|
IotNode.node_number == json_data.get("node_number"), IotNode.id != id
|
|
)
|
|
)
|
|
):
|
|
raise BizException("同编号节点已存在")
|
|
|
|
node.workshop_id = device.workshop_id
|
|
node.status = 0
|
|
db.session.add(node)
|
|
db.session.commit()
|
|
return success()
|
|
|
|
|
|
@bp.put("/<int:id>")
|
|
@jwt_required()
|
|
@bp.doc(security="JWT")
|
|
@permission("iot:node:update")
|
|
@bp.input(NodeUpdateRequest(partial=True), location="json")
|
|
def update_node(id: int, json_data: dict):
|
|
"""
|
|
更新采集节点信息
|
|
"""
|
|
|
|
# 判断节点编号是否唯一
|
|
if json_data.get("node_number") is not None:
|
|
if db.session.scalar(
|
|
select(
|
|
exists().where(
|
|
IotNode.node_number == json_data.get("node_number"), IotNode.id != id
|
|
)
|
|
)
|
|
):
|
|
raise BizException("同编号节点已存在")
|
|
|
|
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("节点信息不存在")
|
|
for key, value in json_data.items():
|
|
if value is not None:
|
|
setattr(node, key, value)
|
|
|
|
db.session.commit()
|
|
|
|
return success()
|
|
|
|
@bp.delete("/<int:id>")
|
|
@jwt_required()
|
|
@bp.doc(security="JWT")
|
|
@permission("iot:node:delete")
|
|
def delete_node(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("采集节点不存在")
|
|
|
|
# 删除节点告警规则
|
|
delete_node_alert_rule(node)
|
|
|
|
# 删除
|
|
db.session.delete(node)
|
|
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["nodeNumber"] = node.node_number
|
|
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):
|
|
"""
|
|
获取采集节点分页
|
|
"""
|
|
query = select(IotNode).order_by(IotNode.created_at.desc())
|
|
if query_data.keyword:
|
|
kw = ModelFilter.escape_like(query_data.keyword)
|
|
query = query.filter(
|
|
IotNode.node_number.like(f"%{kw}%")
|
|
)
|
|
if query_data.endpoint_id:
|
|
query = query.filter(IotNode.endpoint_id == query_data.endpoint_id)
|
|
if query_data.device_id:
|
|
query = query.filter(IotNode.device_id == query_data.device_id)
|
|
elif query_data.workshop_id:
|
|
query = query.filter(IotNode.workshop_id == query_data.workshop_id)
|
|
if query_data.status is not None:
|
|
query = query.filter(IotNode.status == query_data.status)
|
|
|
|
return db.paginate(query, page=query_data.page, per_page=query_data.size)
|
|
|
|
|
|
def get_list(query_data: NodeQuery):
|
|
"""
|
|
获取采集节点列表
|
|
"""
|
|
query = select(IotNode).options(noload(IotNode.workshop), noload(IotNode.device), noload(IotNode.endpoint)).order_by(IotNode.created_at.desc())
|
|
if query_data.keyword:
|
|
kw = ModelFilter.escape_like(query_data.keyword)
|
|
query = query.filter(
|
|
IotNode.node_number.like(f"%{kw}%")
|
|
)
|
|
if query_data.endpoint_id:
|
|
query = query.filter(IotNode.endpoint_id == query_data.endpoint_id)
|
|
if query_data.device_id:
|
|
query = query.filter(IotNode.device_id == query_data.device_id)
|
|
elif query_data.workshop_id:
|
|
query = query.filter(IotNode.workshop_id == query_data.workshop_id)
|
|
if query_data.status is not None:
|
|
query = query.filter(IotNode.status == query_data.status)
|
|
return db.session.scalars(query).all() |