|
|
|
import json
|
|
|
|
from quart import jsonify, request
|
|
|
|
from . import api
|
|
|
|
from web.common.utils import login_required
|
|
|
|
from core.DBManager import mDBM
|
|
|
|
from myutils.ReManager import mReM
|
|
|
|
from core.ModelManager import mMM
|
|
|
|
import cv2
|
|
|
|
import base64
|
|
|
|
|
|
|
|
@api.route('/channel/tree',methods=['GET'])
|
|
|
|
@login_required
|
|
|
|
async def channel_tree(): #获取通道树
|
|
|
|
strsql = ("select t2.area_name ,t1.ID ,t1.channel_name from channel t1 left join area t2 on t1.area_id = t2.id;")
|
|
|
|
data = mDBM.do_select(strsql)
|
|
|
|
channel_tree = [{"area_name": channel[0], "ID": channel[1],"channel_name":channel[2]} for channel in data]
|
|
|
|
return jsonify(channel_tree)
|
|
|
|
|
|
|
|
@api.route('/channel/list',methods=['GET'])
|
|
|
|
async def channel_list(): #获取通道列表 --分页查询,支持区域和通道名称关键字查询
|
|
|
|
strsql = ("select t2.area_name,t1.ID,t1.channel_name,t1.ulr,t1.'type',t1.status,t1.element_id,t4.model_name "
|
|
|
|
"from channel t1 left join area t2 on t1.area_id = t2.id "
|
|
|
|
"left JOIN channel2model t3 on t1.ID = t3.channel_id "
|
|
|
|
"left JOIN model t4 on t3.model_id = t4.ID "
|
|
|
|
"where t1.is_work=1 order by area_name desc;")
|
|
|
|
data = mDBM.do_select(strsql)
|
|
|
|
channel_list = [{"area_name": channel[0], "ID": channel[1], "channel_name": channel[2], "ulr": channel[3],
|
|
|
|
"type": channel[4], "status": channel[5],
|
|
|
|
"element_id": channel[6],"model_name":channel[7]} for channel in data]
|
|
|
|
return jsonify(channel_list)
|
|
|
|
|
|
|
|
@api.route('/channel/info',methods=['GET'])
|
|
|
|
@login_required
|
|
|
|
async def channel_info(): #获取通道信息 ---- list已获取详情
|
|
|
|
return jsonify(1)
|
|
|
|
|
|
|
|
@api.route('/channel/add',methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
async def channel_add(): #新增通道 -- 2024-8-1修改为与修改通道用一个接口
|
|
|
|
json_data = await request.get_json()
|
|
|
|
area = json_data.get('area')
|
|
|
|
cName = json_data.get('cName')
|
|
|
|
Rtsp = json_data.get('Rtsp')
|
|
|
|
cid = int(json_data.get('cid'))
|
|
|
|
|
|
|
|
if mReM.is_valid_rtsp_url(Rtsp) is not True:
|
|
|
|
reStatus = 0
|
|
|
|
reMsg = 'rtsp地址不合法'
|
|
|
|
return jsonify({'status': reStatus, 'msg': reMsg})
|
|
|
|
strsql = f"select id from area where area_name = '{area}';"
|
|
|
|
ret = mDBM.do_select(strsql,1)
|
|
|
|
if ret:
|
|
|
|
strsql = f"select ID from channel where area_id={ret[0]} and channel_name={cName};"
|
|
|
|
data = mDBM.do_select(strsql, 1)
|
|
|
|
if data: #有值--代表重复了
|
|
|
|
reStatus = 0
|
|
|
|
reMsg = "同一区域内的通道名称不能相同!"
|
|
|
|
else:
|
|
|
|
if cid == -1:
|
|
|
|
strsql = (f"INSERT INTO channel (area_id,channel_name,ulr,'type',status) values "
|
|
|
|
f"({ret[0]},'{cName}','{Rtsp}',1,0);")
|
|
|
|
else:
|
|
|
|
strsql = (f"UPDATE channel SET area_id={ret[0]},channel_name='{cName}'"
|
|
|
|
f",ulr='{Rtsp}' where ID={cid};")
|
|
|
|
ret = mDBM.do_sql(strsql)
|
|
|
|
if ret == True:
|
|
|
|
reStatus = 1
|
|
|
|
if cid == -1:
|
|
|
|
reMsg = '添加通道成功'
|
|
|
|
# 对新增的视频通道进行视频采集和
|
|
|
|
strsql = f"select ID from channel where area_id={ret[0]} and channel_name={cName};"
|
|
|
|
data = mDBM.do_select(strsql, 1)
|
|
|
|
if data:
|
|
|
|
cid = data[0]
|
|
|
|
mMM.start_work(cid)
|
|
|
|
else:
|
|
|
|
print("这里不应该没有值!!!!")
|
|
|
|
else:
|
|
|
|
reMsg = '修改通道成功'
|
|
|
|
#需要先停再启动---不区分有没有修改URL了,就当有修改使用
|
|
|
|
mMM.stop_work(cid)
|
|
|
|
mMM.start_work(cid)
|
|
|
|
else:
|
|
|
|
reStatus = 0
|
|
|
|
if cid == -1:
|
|
|
|
reMsg = '添加通道失败,请联系技术支持!'
|
|
|
|
else:
|
|
|
|
reMsg = '修改通道信息失败,请联系技术支持!'
|
|
|
|
else:
|
|
|
|
reStatus = 0
|
|
|
|
reMsg = '错误的区域ID,请修改'
|
|
|
|
return jsonify({'status':reStatus,'msg':reMsg})
|
|
|
|
|
|
|
|
@api.route('/channel/img',methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
async def channel_img():
|
|
|
|
json_data = await request.get_json()
|
|
|
|
cid = int(json_data.get('cid'))
|
|
|
|
channel_data = mMM.verify_list.get_channel(cid)
|
|
|
|
if channel_data:
|
|
|
|
# 执行视频传输
|
|
|
|
ret,frame = channel_data.cap.read()
|
|
|
|
if ret:
|
|
|
|
# 将帧转换为JPEG格式
|
|
|
|
_, buffer = cv2.imencode('.jpg', frame)
|
|
|
|
# 将图像数据编码为Base64
|
|
|
|
img_base64 = base64.b64encode(buffer).decode('utf-8')
|
|
|
|
# 返回JSON响应
|
|
|
|
return jsonify({"image": img_base64})
|
|
|
|
else:
|
|
|
|
return jsonify({"error": "Failed to capture frame"}), 404
|
|
|
|
else:
|
|
|
|
return jsonify({"error": "Channel not found"}), 500
|
|
|
|
|
|
|
|
@api.route('/channel/change',methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
async def channel_change(): #修改通道信息 -- 已弃用
|
|
|
|
area_id = (await request.form)['area_id']
|
|
|
|
channel_id = (await request.form)['channel_id']
|
|
|
|
channel_name = (await request.form)['channel_name']
|
|
|
|
url = (await request.form)['url']
|
|
|
|
if mReM.is_valid_rtsp_url(url) is not True:
|
|
|
|
reStatus = 0
|
|
|
|
reMsg = 'rtsp地址不合法'
|
|
|
|
return jsonify({'status': reStatus, 'msg': reMsg})
|
|
|
|
strsql = f"select area_name from area where id = {area_id};"
|
|
|
|
ret = mDBM.do_select(strsql, 1)
|
|
|
|
if ret:
|
|
|
|
strsql = f"UPDATE channel SET area_id={area_id},channel_name='{channel_name}',ulr='{url}' where ID={channel_id};"
|
|
|
|
ret = mDBM.do_sql(strsql)
|
|
|
|
if ret == True:
|
|
|
|
reStatus = 1
|
|
|
|
reMsg = '修改通道信息成'
|
|
|
|
else:
|
|
|
|
reStatus = 0
|
|
|
|
reMsg = '修改通道信息失败,请联系技术支持!'
|
|
|
|
else:
|
|
|
|
reStatus = 0
|
|
|
|
reMsg = '错误的通道ID,请修改'
|
|
|
|
return jsonify({'status': reStatus, 'msg': reMsg})
|
|
|
|
|
|
|
|
@api.route('/channel/del',methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
async def channel_del(): #删除通道
|
|
|
|
json_data = await request.get_json()
|
|
|
|
cid = int(json_data.get('cid'))
|
|
|
|
mMM.stop_work(cid)
|
|
|
|
#删除该通道和算法的关联信息:布防时间,算法模型数据----使用外键级联删除会方便很多,只要一个删除就可以
|
|
|
|
ret = mDBM.delchannel(cid)
|
|
|
|
if ret == True:
|
|
|
|
reStatus = 1
|
|
|
|
reMsg = '删除通道信息成'
|
|
|
|
else:
|
|
|
|
reStatus = 0
|
|
|
|
reMsg = '删除通道信息失败,请联系技术支持!'
|
|
|
|
return jsonify({'status': reStatus, 'msg': reMsg})
|
|
|
|
|
|
|
|
@api.route('/channel/check',methods=['GET'])
|
|
|
|
@login_required
|
|
|
|
async def channel_check(): #检查通道视频的在线情况--可以获取全部 ID-0,全部,1*具体通道ID--10分钟会更新一次在线状态-- 要验证
|
|
|
|
ID = request.args.get('ID')
|
|
|
|
if ID:
|
|
|
|
ID = int(ID)
|
|
|
|
if ID==0:
|
|
|
|
strsql = "select ID,status from channel;"
|
|
|
|
elif ID > 0:
|
|
|
|
strsql = f"select ID,status from channel where ID={ID};"
|
|
|
|
else:
|
|
|
|
reStatus = 0
|
|
|
|
reMsg = "参数错误"
|
|
|
|
return jsonify({'status': reStatus, 'msg': reMsg})
|
|
|
|
datas = mDBM.do_select(strsql)
|
|
|
|
reStatus = 1
|
|
|
|
reMsg = [{'ID': data[0], 'status': data[1]} for data in datas]
|
|
|
|
return jsonify({'status': reStatus, 'msg': reMsg})
|
|
|
|
else:
|
|
|
|
reStatus = 0
|
|
|
|
reMsg = "参数错误"
|
|
|
|
return jsonify({'status': reStatus, 'msg': reMsg})
|
|
|
|
|
|
|
|
@api.route('/channel/C2M',methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
async def channel_to_model():
|
|
|
|
'''获取通道关联模型的相关数据'''
|
|
|
|
json_data = await request.get_json()
|
|
|
|
cid = int(json_data.get('cid'))
|
|
|
|
#获取算法数据
|
|
|
|
strsql = "select ID,model_name from model;"
|
|
|
|
model_datas = mDBM.do_select(strsql)
|
|
|
|
m_datas = []
|
|
|
|
if model_datas:
|
|
|
|
m_datas = [{'ID':row[0],'model_name':row[1]} for row in model_datas]
|
|
|
|
#获取c2m数据
|
|
|
|
strsql = f"select ID,model_id,check_area,polygon,conf_thres,iou_thres from channel2model where channel_id = {cid};"
|
|
|
|
c2m_data = mDBM.do_select(strsql,1)
|
|
|
|
#schedule数据
|
|
|
|
schedule = []
|
|
|
|
if c2m_data:
|
|
|
|
c2m_data_json = [{'model_id':c2m_data[1],'check_area':c2m_data[2],'polygon':c2m_data[3],
|
|
|
|
'conf_thres':c2m_data[4],'iou_thres':c2m_data[5]}]
|
|
|
|
c2m_id = c2m_data[0]
|
|
|
|
strsql = f"select day,hour,status from schedule where channel2model_id ={c2m_id} order by hour asc,day asc;"
|
|
|
|
schedule_datas = mDBM.do_select(strsql)
|
|
|
|
if schedule_datas:
|
|
|
|
schedule = [{'day': row[0], 'hour': row[1], 'status': row[2]} for row in schedule_datas]
|
|
|
|
else:
|
|
|
|
schedule = []
|
|
|
|
else:
|
|
|
|
schedule = []
|
|
|
|
c2m_data_json = []
|
|
|
|
#返回数据
|
|
|
|
redata = {"m_datas":m_datas,"c2m_data":c2m_data_json,"schedule":schedule}
|
|
|
|
return jsonify(redata)
|
|
|
|
|
|
|
|
@api.route('/channel/area/list',methods=['GET'])
|
|
|
|
@login_required
|
|
|
|
async def channel_area_list(): #获取区域列表
|
|
|
|
strsql = "select * from area;"
|
|
|
|
datas = mDBM.do_select(strsql)
|
|
|
|
reMsg = [{'id': data[0], 'area_name': data[1]} for data in datas]
|
|
|
|
return jsonify(reMsg)
|
|
|
|
|
|
|
|
@api.route('/channel/area/change',methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
async def channel_area_change(): #修改区域名称
|
|
|
|
area_id = (await request.form)['id']
|
|
|
|
area_name = (await request.form)['name']
|
|
|
|
strsql = f"update area set area_name='{area_name}' where id = {area_id};"
|
|
|
|
ret = mDBM.do_sql(strsql)
|
|
|
|
if ret == True:
|
|
|
|
reStatus = 1
|
|
|
|
reMsg = '修改通道名称成功'
|
|
|
|
else:
|
|
|
|
reStatus = 0
|
|
|
|
reMsg = '修改通道名称失败,请联系技术支持!'
|
|
|
|
return jsonify({'status': reStatus, 'msg': reMsg})
|
|
|
|
|
|
|
|
@api.route('/channel/area/del',methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
async def channel_area_del(): #删除区域
|
|
|
|
area_id = (await request.form)['id']
|
|
|
|
strsql = f"select * from channel where area_id={area_id};"
|
|
|
|
datas = mDBM.do_select(strsql)
|
|
|
|
if datas:
|
|
|
|
reStatus = 0
|
|
|
|
reMsg = '该区域下配置了通道,请先删除通道后,再删除区域!'
|
|
|
|
else:
|
|
|
|
strsql = f"delete from area where id={area_id};"
|
|
|
|
ret = mDBM.do_sql(strsql)
|
|
|
|
if ret == True:
|
|
|
|
reStatus = 1
|
|
|
|
reMsg = '删除区域成功'
|
|
|
|
else:
|
|
|
|
reStatus = 0
|
|
|
|
reMsg = '删除区域失败,请联系技术支持!'
|
|
|
|
return jsonify({'status': reStatus, 'msg': reMsg})
|
|
|
|
|
|
|
|
@api.route('/channel/area/add',methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
async def channel_area_add(): #添加区域
|
|
|
|
area_name = (await request.form)['name']
|
|
|
|
strsql = f"insert into area (area_name) values ('{area_name}');"
|
|
|
|
ret = mDBM.do_sql(strsql)
|
|
|
|
if ret == True:
|
|
|
|
reStatus = 1
|
|
|
|
reMsg = '新增区域成功'
|
|
|
|
else:
|
|
|
|
reStatus = 0
|
|
|
|
reMsg = '新增区域失败,请联系技术支持!'
|
|
|
|
return jsonify({'status': reStatus, 'msg': reMsg})
|
|
|
|
|
|
|
|
@api.route('/channel/model/list',methods=['GET'])
|
|
|
|
@login_required
|
|
|
|
async def channel_model_list(): #获取算法列表
|
|
|
|
strsql = "select ID,model_name,version from model;"
|
|
|
|
datas = mDBM.do_select(strsql)
|
|
|
|
reMsg = {}
|
|
|
|
if datas:
|
|
|
|
reMsg = [{'ID': data[0], 'model_name': data[1],'version':data[2]} for data in datas]
|
|
|
|
return jsonify(reMsg)
|
|
|
|
|
|
|
|
@api.route('/channel/model/linklist',methods=['GET'])
|
|
|
|
@login_required
|
|
|
|
async def channel_model_linklist(): #获取算法列表 --关联算法时展示 --没调用。。
|
|
|
|
ID = request.args.get('ID') #通道ID
|
|
|
|
strsql = (f"select t1.ID,t2.model_name from channel2model t1 left join model t2 "
|
|
|
|
f"on t1.model_id=t2.ID where channel_id={ID};")
|
|
|
|
datas = mDBM.do_select(strsql)
|
|
|
|
reMsg = {}
|
|
|
|
if datas:
|
|
|
|
reMsg = [{'ID': data[0], 'model_name': data[1]} for data in datas]
|
|
|
|
return jsonify(reMsg)
|
|
|
|
|
|
|
|
@api.route('/channel/model/linkmodel',methods=['POST']) #--没调用。。
|
|
|
|
@login_required
|
|
|
|
async def channel_model_linkmodel(): #获取算法列表 --关联算法时展示 #?关联算法时需要初始化布防计划,同样删除的需要删除
|
|
|
|
channel_id = (await request.form)['channel_id']
|
|
|
|
model_list = json.loads((await request.form)['model_list'])
|
|
|
|
#? 需要对channel_id和model_list的是否在数据库要进行一个检查
|
|
|
|
reStatus = 0
|
|
|
|
reMsg = '提交的参数错误,请检查!'
|
|
|
|
strsql = f"select ID from channel where ID={channel_id};"
|
|
|
|
if mDBM.do_select(strsql,1): #通道号在数据库中
|
|
|
|
for model_id in model_list:
|
|
|
|
strsql = f"select ID from model where ID = {model_id};"
|
|
|
|
if not mDBM.do_select(strsql,1):
|
|
|
|
return jsonify({'status': reStatus, 'msg': reMsg})
|
|
|
|
ret =mDBM.updateC2M(channel_id,model_list)
|
|
|
|
if ret == True:
|
|
|
|
reStatus = 1
|
|
|
|
reMsg = '修改关联算法成功'
|
|
|
|
else:
|
|
|
|
reStatus = 0
|
|
|
|
reMsg = '修改关联算法失败,请联系技术支持!'
|
|
|
|
return jsonify({'status': reStatus, 'msg': reMsg})
|
|
|
|
|
|
|
|
@api.route('/channel/model/getarea',methods=['GET'])
|
|
|
|
@login_required
|
|
|
|
async def channel_model_getarea(): #获取算法区域的备注信息 --- 同时获取检测阈值
|
|
|
|
ID = request.args.get('ID')
|
|
|
|
strsql = f"select check_area,polygon,conf_threshold from channel2model where ID={ID};"
|
|
|
|
data = mDBM.do_select(strsql,1)
|
|
|
|
if data:
|
|
|
|
reMsg = {'ID':ID,'check_area':data[0],'polygon':data[1],'conf_threshold':data[2]}
|
|
|
|
else:
|
|
|
|
reMsg = {}
|
|
|
|
return jsonify(reMsg)
|
|
|
|
|
|
|
|
@api.route('/channel/model/changearea',methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
async def channel_model_changearea(): #修改算法检测区域信息
|
|
|
|
ID = (await request.form)['ID']
|
|
|
|
check_area = (await request.form)['check_area']
|
|
|
|
check_x = (await request.form)['polygon']
|
|
|
|
strsql = (f"update channel2model set check_area={check_area},polygon={check_x} where ID={ID};")
|
|
|
|
ret = mDBM.do_sql(strsql)
|
|
|
|
if ret == True:
|
|
|
|
reStatus = 1
|
|
|
|
reMsg = '修改算法检测区域成功'
|
|
|
|
#需要重启视频通道的执行程序 --需要cid
|
|
|
|
#?
|
|
|
|
else:
|
|
|
|
reStatus = 0
|
|
|
|
reMsg = '新修改算法检测区域失败,请联系技术支持!'
|
|
|
|
return jsonify({'status': reStatus, 'msg': reMsg})
|
|
|
|
|
|
|
|
@api.route('/channel/model/changethreshold',methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
async def channel_model_changthreshold(): #修改算法阈值
|
|
|
|
ID = (await request.form)['ID']
|
|
|
|
conf_threshold = (await request.form)['conf_threshold']
|
|
|
|
|
|
|
|
strsql = (f"update channel2model set conf_threshold={conf_threshold} where ID={ID};")
|
|
|
|
ret = mDBM.do_sql(strsql)
|
|
|
|
if ret == True:
|
|
|
|
reStatus = 1
|
|
|
|
reMsg = '修改算法的阈值成功'
|
|
|
|
else:
|
|
|
|
reStatus = 0
|
|
|
|
reMsg = '新修改算法的阈值失败,请联系技术支持!'
|
|
|
|
return jsonify({'status': reStatus, 'msg': reMsg})
|
|
|
|
|
|
|
|
@api.route('/channel/model/getschedule',methods=['GET'])
|
|
|
|
@login_required
|
|
|
|
async def channel_model_getschedule(): #获取算法的布防时间
|
|
|
|
ID = request.args.get('ID')
|
|
|
|
strsql = f"select day,hour,status from schedule where channel2model_id={ID};"
|
|
|
|
datas = mDBM.do_select(strsql)
|
|
|
|
if datas:
|
|
|
|
reMsg = [{'day': data[0], 'hour': data[1],'status':data[2]} for data in datas]
|
|
|
|
else:
|
|
|
|
reMsg = {}
|
|
|
|
return jsonify(reMsg)
|
|
|
|
|
|
|
|
@api.route('/channel/model/changeschedule',methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
async def channel_model_changeschedule(): #修改算法的布防时间
|
|
|
|
ID = (await request.form)['ID']
|
|
|
|
schedule_data_str = (await request.form)['schedule_data']
|
|
|
|
schedule_data = json.loads(schedule_data_str.replace("'", '"'))
|
|
|
|
for day,hours in schedule_data.items():
|
|
|
|
for hour,status in enumerate(hours):
|
|
|
|
strsql = (f"insert into schedule (channel2model_id,day,hour,status) values ({ID},'{day}',{hour},{status})"
|
|
|
|
f" on conflict(channel2model_id,day,hour) do update set status=excluded.status;")
|
|
|
|
ret = mDBM.do_sql(strsql)
|
|
|
|
if ret == False:
|
|
|
|
reStatus = 0
|
|
|
|
reMsg = '修改监测区域失败,请联系技术支持!'
|
|
|
|
return jsonify({'status': reStatus, 'msg': reMsg})
|
|
|
|
reStatus = 1
|
|
|
|
reMsg = '修改监测区域成功'
|
|
|
|
return jsonify({'status': reStatus, 'msg': reMsg})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|