import sys
import json,os
from json import JSONDecodeError
import pymysql
from django.db.models import Sum, Max
from django.conf import settings

from smartfarming.models.device import (
    MongoDevice, 
    MongoCBDData, 
    MongoBZYData, 
    MongoSCDData, 
    MongoXYCBData, 
    DevicePestWarning,
)
from smartfarming.models.weather import QXZThresholdWarning
from smartfarming.models.worm_forecast import MongoCBDphoto
from smartfarming.api.views.forecast.all_dict import insect_dict, attract_discern
from kedong.decoration import kedong_deco, PortError
from smartfarming.utils import expire_time
config_dict = settings.CONFIG


config = {
        'host': config_dict['bigdata']['mysql_host'],
        'port': int(config_dict['bigdata']['mysql_port']),
        'user': config_dict['bigdata']['mysql_user'],
        'password': config_dict['bigdata']['mysql_password'],
        'db': config_dict['bigdata']['mysql_db'],
        'charset': 'utf8mb4',
        'cursorclass': pymysql.cursors.DictCursor,
    }


@kedong_deco(login_required=True)
def lamp_list(request):
    """
    设备列表的
    测报系统 :虫情测报灯,孢子仪
    参数:
    device_type_id          必传  (string)                  测报系统的设备类型   3虫情测报灯 7孢子仪 
    page                    非必传(num)                     页码,默认为1
    page_size               非必传(num)                     每页数量, 不传默认为所有设备列表,一页展示全部,用与测报灯投屏, 传值代表每页数量

    device_id               非必传(string)                  搜索项。设备id
    device_name             非必传(string)                  搜索项。设备名称
    device_status           非必传(string)                  搜索项。状态id
    返回值:
    {
    "data": [
        {
            "device_name": "这里是设备名称",                 设备名称
            "imei": "6886565004320786589",                  设备id
            "is_online": 1,                                 0离线 1在线
            "addtime": 1590147148,                          时间戳
            "dtype": "DCCBD-2_HK77"                         设备型号/类型
            "address":'',                                   设备地址
            "cultivate_time":       培养液更换时间,
            "status_cul":          培养液状态 0未到期,1已到期,2即将到期,
            "glass_slide_time":    载玻片更换时间,
            "status_glass":        载玻状态 0未到期,1已到期,2即将到期
        }
    ],
    "errorCode": 0,
    "message": "",
    "formError": {}
    }
    """
    post_info = request.POST
    device_id = post_info.get('device_id','')
    device_name = post_info.get('device_name','')
    page = int(post_info.get('page', 1))
    page_size = post_info.get('page_size')
    device_model = post_info.get("device_model", '')
    device_status = post_info.get("device_status", '')
    device_code = ''
    try:
        type_id = int(post_info.get("device_type_id", ''))
    except Exception as e:
        raise PortError('device_type_id', '查看设备类型不存在')
    search_dict = {}
    search_dict["device_type_id"] = type_id
    devices = MongoDevice.objects.all().order_by('-device_status', '-addtime')
    if device_status:
        device_status = int(device_status)
        search_dict["device_status"] = device_status
    if device_id:
        devices = devices.filter(Q(device_id__icontains=device_id) | Q(device_name__icontains=device_id))
    if device_name:
        devices = devices.filter(device_name__icontains=device_name)
    devices = devices.filter(**search_dict)  # 所有的测报灯
    counts = devices.count()
    if page_size:
        page_size = int(page_size)
        start = max((page - 1), 0) * page_size
        end = page * page_size
        devices = devices[start:end]
    data = []
    for i in devices:
        real_name = ""
        sale_user = ""
        device_model, device_code, decoy = "", "", ""
        xy_expire = "未设置诱芯到期时间"
        xy_uptime = 0
        if type_id == 4:
            device_model = i.device_model
            device_code = i.device_code
            decoy = i.decoy
            xy_uptime = i.xy_uptime
            xy_expire_time = i.xy_expire_time
            nowtime_stamp = int(time.time())
            if xy_expire_time == 0:
                xy_expire = "未设置诱芯到期时间"
            elif xy_expire_time !=0 and nowtime_stamp > xy_expire_time:
                xy_expire = "诱芯已经到期"
            elif xy_expire_time !=0 and (xy_expire_time-nowtime_stamp) <= 60*60*24*7:
                xy_expire = "诱芯即将到期，请注意更换"
            else:
                xy_expire = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(xy_expire_time))
        if xy_uptime == 0:
            xy_uptime = "暂无"
        else:
            xy_uptime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(xy_uptime))
        glass_slide_time = i.glass_slide_time
        cultivate_time = i.cultivate_time
        status_cul = ""
        status_glass = ""
        if type_id == 7:
            if cultivate_time:
                status_cul = expire_time(cultivate_time)
            if glass_slide_time:
                status_glass = expire_time(glass_slide_time)
        data.append({
            "d_id": i.id,
            "imei": i.device_id,
            "device_name": i.device_name,
            "is_online": i.device_status,
            "dtype": i.dver_num,
            "addtime": i.addtime,
            "uptime" : i.uptime,
            "device_code": device_code,
            "xy_expire": xy_expire,
            "xy_uptime": xy_uptime,
            "sale_user": sale_user,
            "device_model": device_model,
            "address": i.province + i.city + i.district,
            "lat": str(i.lat).strip('0'),
            "lng": str(i.lng).strip('0'),
            "decoy": decoy,
            "disable": i.disable,
            "real_name": real_name,
            "networking": i.networking,
            "equipment_status": i.equipment,
            "salesman_task_number": i.salesman_task_number,
            "device_expire_days": i.device_expire_days,
            "device_expire_time": i.device_expire_time,
            "device_expire": i.device_expire,
            "cultivate_time": cultivate_time,
            "status_cul": status_cul,
            "glass_slide_time": glass_slide_time,
            "status_glass": status_glass,
        })
    return {"data":data,"counts":counts}




def device_status_data(request):
    """
    虫情测报灯/数据详情
    设备实时状态接口
        参数:
        device_id               必传                            设备id

        返回值:
        "data": {
        "upds": 1,              上仓门状态 1打开,0关闭
        "tpl": 5,               低温保护阈值温度
        "dver": "1.0.0",        设备固件版本
        "gs": 0,                通道状态 1落虫,0排水
        "hs": 0,                加热状态 1加热,0正常
        "dnds": 0,              下仓门状态 1打开,0关闭
        "is_online": 0,         在线状态
        "csq": 29,              信号强度
        "tph": 70,              高温保护阈值温度
        "ts": 0                 定时模式 0光控,1时控
        "tps": 1                温控状态 1 温控,0 正常
        "lps": 0                光控状态 1 光控,0 正常
        "hrt": 22               加热仓实时温度
        "device_name":"这里是设备名称",
        "address": "这里是设备位置",
        "iccid": 1234444  SIM卡号
    }
    """
    post_info = request.POST
    _device_id = post_info.get("device_id")
    if not _device_id:
        raise PortError('device_id', "该设备不存在")
    try:
        device = MongoDevice.objects.get(device_id=_device_id)
    except:
        raise PortError('device_id','暂无此设备')
    d_id = device.id
    device_name = device.device_name
    province = device.province
    city = device.city
    district = device.district
    device_status = device.device_status  # 在线状态


    myuser_type = request.user_type

    device_datas = MongoCBDData.objects.filter(device_id=d_id).order_by('-id')
    

    try:
        device_data = json.loads(device_datas[0].device_data)
    except JSONDecodeError as e:
        device_data = eval(device_datas[0].device_data)
    except:
        raise PortError("device_id","暂无数据")
    
    ds = device_data.get("ds",1 )
    ts = device_data.get("ts",1)
    up_st = {
        "is_online": device_status,
        "ts":ts,
        "hs":device_data["hs"],
        "upds":device_data["upds"],
        "dnds":device_data["dnds"],
        "csq":device_data["csq"],
        "dver":device_data["dver"],
        "tph":device_data["tph"],
        "tpl":device_data["tpl"],
        "tps":device_data["tps"],
        "lps":device_data["lps"],
        "hrt":device_data["hrt"],
        "iccid":device_data["iccid"],
        "rps":device_data["rps"],
        "ah":device_data["ah"],
        "at":device_data["at"],
        "ds":ds,
        "device_name":device_name,
        "address": province + city + district,
    }
    return up_st


@kedong_deco(login_required=True)
def device_history_data(request):
    """
    虫情测报灯/孢子仪    数据详情页面/列表展示
    设备历史状态列表接口
    参数:
    device_type_id          必传（string）                  设备类型  3虫情测报灯 7孢子仪
    device_id               非必传                          设备id
    page                    非必传(num)                     页码,默认为1
    page_size               非必传(num)                     每页数量,默认为10
    start_time              必传(string 时间戳)              开始时间    (用于时间搜索)
    end_time                必传(string 时间戳)              结束时间    (用于时间搜索)

    返回值:
    "data": {
        "device_id": "28586565004320786510437",  设备id
        "counts": 3,                            列表数据总长度
        "data": [
            {

                "status": {
                        "addtime": 1590230470,      时间
                        "csq":29,					//信号强度
                        "hrt":55,					//加热仓实时温度 °C
                        "at":245,					//环境温度 °C(注:温度值为乘以 10 后的结果,需要除以 10 得到温度值)
                        "ah":745,					//环境湿度 %RH(注:湿度值为乘以 10 后的结果,需要除以 10 得到相对湿度值)
                        "dtype":1,					//设备类型 <测报灯设备类型为 3>
                        "dver":"1.0.0",				//设备固件版本
                        "rps":0,					//雨控状态 1雨控,0正常,下同
                        "lps":0,					//光控状态 1光控,0正常
                        "tps":0,					//温控状态 1温控,0正常
                        "gs":0,						//通道状态 1落虫,0排水
                        "upds":1,					//上仓门状态 1打开,0关闭
                        "dnds":0,					//下仓门状态 1打开,0关闭
                        "hs":0,						//加热状态 1加热,0正常
                        "lat":"34.815187",			//纬度
                        "lng":"113.67336",			//经度
                        "stamp":"20180301211805",	//时间戳
                        "ws":0,                     //工作状态0待机 1工作
                        "vbat":"24",                 //电源电压
                        "batStatus":0,              //电压状态0正常 1欠压
                        "st":20,                    //时控开始时间
                        "et":0,                     //时控结束时间
                        "ts":1,                     //定时模式 0 光控,1时控
                        "collt":10,                 //落虫收集时间
                        "htim":10,                  //设定的虫体烘干时间
                        "hst":110,                  //设定的加热温度
                        "tph":70,                   //高温保护阀值
                        "tpl":0,                    //低温保护阀值
                        "boot":0,                   //禁止工作 0-正常  1-使能（禁止工作）
                        "shake_sec":1,              //震动时间
                        "lamp":0,                   //灯管状态0-正常,1-异常
                        "lux":100                  //光照强度
                }......
            },
        ]
        }

    """
    post_info = request.POST
    device_type_id = post_info.get("device_type_id")
    start_time = post_info.get('start_time')
    end_time = post_info.get('end_time')
    if not device_type_id:
        raise PortError("device_type_id", "没有对应型号设备")
    _device_id = post_info.get("device_id")

    if not _device_id:
        raise PortError('device_id',"该设备不存在")
    try:
        device = MongoDevice.objects.get(device_id=_device_id)
    except:
        raise PortError('device_id',"暂无此设备")
    device_id = device.id

    #  3虫情测报灯 7孢子仪
    if device_type_id == "7":
        models =  "sa_device_bzy_data"
        mode = MongoBZYData
    elif device_type_id == "3":
        models =  "sa_device_cbd_data"
        mode = MongoCBDData
    elif device_type_id == "2":
        models = "sa_device_scd_data"
        mode = MongoSCDData
    elif device_type_id == "4":
        models =  "sa_device_xycb_data"
        mode = MongoXYCBData
    else:
        raise PortError('device_id',"暂不支持该设备类型")

    connection = pymysql.connect(**config)
    cursor = connection.cursor()

    counts = mode.objects.filter(device_id=device_id,addtime__range=(start_time,end_time)).count()

    page = int(post_info.get('page', 1))
    page_size = int(post_info.get('page_size', 10))
    start = max((page - 1), 0) * page_size
    where_str = ''

    if start_time:
        if start_time.isdigit() and end_time.isdigit():
            start_time = int(start_time)
            end_time = int(end_time)
        else:
            raise PortError("","参数类型不对")
        where_str += ' and (addtime  between {} and {})'.format(start_time, end_time)

    sql = 'select id, device_data, addtime from {} where device_id={} {} order by addtime desc limit {},{}'.format(
        models, device_id, where_str,start,page_size)
    cursor.execute(sql)
    result = cursor.fetchall()
    _device_datas = result
    data = []
    if _device_datas:
        for j in _device_datas:
            d_h_t = eval(j["device_data"])
            d_h_t["addtime"] = j["addtime"]
            data.append({"d_h_t":d_h_t})
    if cursor:
        cursor.close()
    if connection:
        connection.close()
    return {
        "data": data,
        "counts": counts
    }



@kedong_deco(login_required=True)
def device_polyline_data(request):
    """
    虫情测报灯/性诱测报/孢子仪/杀虫灯
    数据详情-折线图接口
    参数:
    device_type_id          必传（string）                  设备类型  3虫情测报灯 7孢子仪 4智能性诱 2杀虫灯  9糖醋测报灯  10测报灯rtu
    d_id                    必传                            设备id
    start_time              非必传(string 时间戳)           开始时间    (用于时间搜索)
    end_time                非必传(string 时间戳)           结束时间    (用于时间搜索)

    返回值:
    "data": {
        "device_id": "28586565004320786510437",  设备id
        "ath": [
            {
                "addtime": 1590230470,          时间
                "temperature": 34.1,            温度
                "humidity": 27.6,               湿度
                "others": 33,                   设备类型是3为加热仓温度 当设备类型为7为保温仓温度 为4的时候是cpu温度 为2时是电击次数
                "set_temp": 50,                 设备类型是7时为孢子仪保温仓设定温度,其他类型时该值为空
            }......
    """
    post_info = request.POST
    device_type_id = post_info.get("device_type_id")
    start_time = post_info.get('start_time')
    end_time = post_info.get('end_time')
    if not device_type_id:
        raise PortError("device_type_id", "没有对应型号设备")
    d_id = post_info.get("d_id")
    if not d_id:
        raise PortError('d_id', "请输入设备id")

    try:
        device = MongoDevice.objects.get(id=d_id)
        device_expire = device.device_expire
        device_expire_time = device. device_expire_time
    except:
        raise PortError('device_id',"暂无此设备")

    if device_type_id == "7":
        models =  "sa_device_bzy_data"
        mode = MongoBZYData
    elif device_type_id == "4":
        models =  "sa_device_xycb_data"
        mode = MongoXYCBData
    elif device_type_id == "2":
        models =  "sa_device_scd_data"
        mode = MongoSCDData
    elif device_type_id == "3":
        models =  "sa_device_cbd_data"
        mode = MongoCBDData
    else:
        raise PortError('device_id',"暂不支持该设备类型")

    counts = mode.objects.filter(device_id=d_id,addtime__range=(start_time,end_time)).count()
    limit = ""
    if counts >= 400:
        limit = "limit 400"
    else:
        limit = "limit {}".format(counts)

    connection = pymysql.connect(**config)
    cursor = connection.cursor()
    result = ""
    ath = []
    myuser_type = request.user_type
    if not myuser_type == 1 and device_expire == "1":
        if start_time and int(end_time) > int(device_expire_time):
            end_time = device_expire_time

        sql = 'select id,device_data,addtime from {}  where device_id={} and  addtime between {} and {} ORDER BY addtime {} '.format(models,d_id,start_time,end_time,limit)
        cursor.execute(sql)
        result = cursor.fetchall()
    else:
        if start_time:
            sql = 'select id,device_data,addtime FROM {} where device_id = {} and addtime between {} and {} ORDER BY addtime {}'.format(models,int(d_id),start_time,end_time,limit)
        #sql = 'select id,device_data,addtime from(select id,device_data,addtime from {} where device_id = {})as t where addtime between {} and {} ORDER BY id {}'.format(models,int(d_id),start_time,end_time,limit)
        # sql = 'select device_data, addtime from {} where device_id={} and  addtime between {} and {}'.format(models,d_id,start_time,end_time)
            cursor.execute(sql)
            result = cursor.fetchall()

    if cursor:
        cursor.close()
    if connection:
        connection.close()
    if result:
        for i in result:
            d_t = eval(i['device_data'])
            try:
                temperature = d_t["at"]
                humidity = d_t["ah"]
            except:
                temperature = 0
                humidity = 0
            try:
                new_tem = d_t["new_tem"]
                new_hum = d_t["new_hum"]
            except:
                new_tem = ""
                new_hum = ""
            others = ''
            set_temp = ''
            if device_type_id == '3':
                try:
                    others = d_t["hrt"]
                except:
                    continue
            elif device_type_id == '2':
                try:
                    others = {
                        "ct": d_t["ct"],
                        "cv": d_t["cv"],
                        "bv": d_t["bv"],
                    }
                except:
                    others = {
                        "ct": "0",
                        "cv": "13.905",
                        "bv": "13.227",
                    }
            elif device_type_id == '7':
                try:
                    others = d_t["pre_temp"]
                    set_temp = d_t["set_temp"]
                except:
                    others = "0"
                    set_temp = "0"
            elif device_type_id == '4':
                try:
                    others = {
                        "wind_drec":d_t["wind_drec"],
                        "wind_sped":d_t["wind_sped"],
                    }
                except:
                    try:
                        others = {
                            "volt_ct":d_t["volt_ct"],
                            "infr_ct":d_t["infr_ct"],
                        }
                    except:
                        raise PortError('device_id',"该设备数据出错")
            elif device_type_id == "9":
                others = d_t["csq"]
            ath.append({
                "temperature":temperature,
                "humidity":humidity,
                "others":others,
                "addtime": i["addtime"],
                "set_temp":set_temp,
                "new_tem": new_tem,
                "new_hum":new_hum,
            })
    return ath


@kedong_deco(login_required=True)
def pest_raise_info(request):
    """
    害虫统计页面
    害虫浮现日期

    参数:
    d_ids                   必传                            设备自增ID
    identify_model          必传                            识别模型('A'为识别模型A,'B'为识别模型B)
    year                    必传                            年份
    amend                   必传                            机器'0'或者人为'1',不传默认为'0'机器识别

    return:
    data返回值字段,pest_info害虫信息,pest_list害虫列表
    "data": {
        "pest_info": {
            "棉铃虫": {
                "startTime": "2022-07-07",
                "highTime": "2022-07-12",
                "endTime": "2022-07-12",
                "highNum": 29
            },
            ...
        },
        "pest_list": [
            "棉铃虫",
            "东方粘虫",
            "小地老虎",
            "铜绿丽金龟",
            "黄褐丽金龟"
        ]
    }

    """
    parameters = request.POST
    d_ids = parameters.get("d_ids")
    year = parameters.get("year")
    amend = parameters.get("amend","0")
    
    # 获取统计设备列表
    if d_ids:
        d_id_list = [int(d_id) for d_id in d_ids.split(",")]
    else:
        raise PortError("d_ids","参数缺失")
        
    # 获取年份位于时间戳段
    start_date = year+"-01-01 00:00:00"
    end_date = year+"-12-31 23:59:59"
    start_time = time.strptime(start_date,"%Y-%m-%d %H:%M:%S")
    end_time = time.strptime(end_date,"%Y-%m-%d %H:%M:%S")
    start_stamp = int(time.mktime(start_time))
    end_stamp = int(time.mktime(end_time))
    
    # 统计
    photo_queryset = MongoCBDphoto.objects.filter(device_id__in=d_id_list,photo_status=1,addtime__range=(start_stamp,end_stamp))
    if amend == "0":
        photo_queryset = photo_queryset.filter(~Q(indentify_result="")).order_by("addtime")
    else:
        photo_queryset = photo_queryset.filter(~Q(indentify_result="") | ~Q(mark="")).order_by("addtime")
    pest_info = {}
    pest_day_info = {}
    time_recording = 0
    for photo_object in photo_queryset:
        addtime = photo_object.addtime
        time_serialize = time.strftime("%Y-%m-%d",time.localtime(addtime))
        # 按天归档
        if time_serialize != time_recording:
            for pest_day_key,pest_day_value in pest_day_info.items():
                if pest_day_key in pest_info:
                    pest_info[pest_day_key]["endTime"] = pest_day_value["endTime"]
                    if pest_day_value["highNum"] >= pest_info[pest_day_key]["highNum"]:
                        pest_info[pest_day_key]["highTime"] = pest_day_value["highTime"]
                        pest_info[pest_day_key]["highNum"] = pest_day_value["highNum"]
                else:
                    pest_info[pest_day_key] = pest_day_value
            pest_day_info.clear()
            time_recording = time_serialize
        # 单张照片结果
        indentify_result = photo_object.indentify_result
        mark = photo_object.mark
        if amend == "1" and mark:
            mark = json.loads(mark)
            for label in mark:
                pest_name = label.get("text")
                pest_num = 1
                if pest_name in pest_day_info:
                    pest_day_info[pest_name]["highNum"] += pest_num
                else:
                    pest_day_info[pest_name] = {"startTime":time_serialize,"highTime":time_serialize,"endTime":time_serialize,"highNum":pest_num}
        else:
            for result in indentify_result.split("#"):
                tuple_result = result.split(",")
                pest_name = insect_dict.get(tuple_result[0],"未命名")
                pest_num = int(tuple_result[1])
                if pest_name in pest_day_info:
                    pest_day_info[pest_name]["highNum"] += pest_num
                else:
                    pest_day_info[pest_name] = {"startTime":time_serialize,"highTime":time_serialize,"endTime":time_serialize,"highNum":pest_num}
    # 最后一天的数据统计,循环内加不了
    for pest_day_key,pest_day_value in pest_day_info.items():
        if pest_day_key in pest_info:
            pest_info[pest_day_key]["endTime"] = pest_day_value["endTime"]
            if pest_day_value["highNum"] >= pest_info[pest_day_key]["highNum"]:
                pest_info[pest_day_key]["highTime"] = pest_day_value["highTime"]
                pest_info[pest_day_key]["highNum"] = pest_day_value["highNum"]
        else:
            pest_info[pest_day_key] = pest_day_value
    return {"pest_info":pest_info,"pest_list":list(pest_info.keys())}
        


@kedong_deco(login_required=True)
def pest_statistics_char_new(request):
    """
    害虫统计页面
    害虫变化趋势折线图
    参数:
    d_ids                   必传                            设备自增ID
    amend                   必传                            机器'0'或者人为'1',不传默认为'0'机器识别
    start_time              必传(string 秒级时间戳)          开始时间    (用于时间搜索)
    end_time                必传(string 秒级时间戳)          结束时间    (用于时间所有)

    返回值:
    单台设备会有at,ah,多台设备情况下不会有at,ah
    "data": {
        "char_data": {
            "棉铃虫": [
                {
                    "addtime": 1657123200,
                    "sum": 29,
                    "at": 24,
                    "ah": 38
                },
                ...
            ],
            ...
        },
        "pest_total": {
            "蓝目天蛾": 1,
            "黑绒绢金龟": 1,
            "瓢虫": 1,
            "铜绿丽金龟": 3,
            "黄褐丽金龟": 3,
            "小地老虎": 6,
            "东方粘虫": 66,
            "棉铃虫": 87
        },
        "at_ah_info": [
            {
                "addtime": 1657123200,
                "at": 24,
                "ah": 38
            },
            ...
        ]
    },
    """
    parameters = request.POST
    d_ids = parameters.get("d_ids")
    start_time = int(parameters.get("start_time"))
    end_time = int(parameters.get("end_time"))
    amend = parameters.get("amend","0")

    
    # 获取统计设备列表
    if d_ids:
        d_id_list = [int(d_id) for d_id in d_ids.split(",")]
    else:
        raise PortError("d_ids","参数缺失")
    # 统计
    photo_queryset = MongoCBDphoto.objects.filter(device_id__in=d_id_list,photo_status=1,addtime__range=(start_time,end_time))
    if amend == "0":
        photo_queryset = photo_queryset.filter(~Q(indentify_result="")).order_by("addtime")
    else:
        photo_queryset = photo_queryset.filter(~Q(indentify_result="") | ~Q(mark="")).order_by("addtime")

    chart_info = {}
    pest_day_info = {}
    at_day_info = []
    ah_day_info = []
    at_ah_info = []
    pest_info_total = {}
    time_recording = 0
    for photo_object in photo_queryset:
        addtime = photo_object.addtime
        time_date = time.strftime("%Y-%m-%d",time.localtime(addtime))
        date_stamp = int(time.mktime(time.strptime(time_date,"%Y-%m-%d")))
        
        # 按天归档
        if date_stamp != time_recording:
            for pest_day_key,pest_day_value in pest_day_info.items():
                if pest_day_key in chart_info:
                    chart_info[pest_day_key].append(pest_day_value)
                else:
                    chart_info[pest_day_key] = []
                    chart_info[pest_day_key].append(pest_day_value)
            if len(d_id_list) == 1: # 单台设备可以来获取温湿度,多台设备不能获取温湿度
                if time_recording != 0:
                    at_avg = int(sum(at_day_info)//len(at_day_info)) if len(at_day_info)!=0 else 25
                    ah_avg = int(sum(ah_day_info)//len(ah_day_info)) if len(ah_day_info)!=0 else 30
                    at_ah_info.append({"addtime":time_recording,"at":at_avg,"ah":ah_avg})

            pest_day_info.clear()
            at_day_info.clear()
            ah_day_info.clear()
            time_recording = date_stamp

        # 单张照片结果
        if len(d_id_list) == 1:
            at = eval(photo_object.at) if photo_object.at else 0
            ah = eval(photo_object.ah) if photo_object.ah else 0
            if at != 0:
                at_day_info.append(at)
            if ah != 0:
                ah_day_info.append(ah)

        indentify_result = photo_object.indentify_result
        mark = photo_object.mark
        if amend == "1" and mark:
            mark = json.loads(mark)
            for label in mark:
                pest_name = label.get("text")
                pest_num = 1
                if pest_name in pest_day_info:
                    pest_day_info[pest_name]["sum"] += pest_num
                else:
                    pest_day_info[pest_name] = {"addtime":date_stamp,"sum":pest_num}
                if pest_name in pest_info_total:
                    pest_info_total[pest_name] += pest_num
                else:
                    pest_info_total[pest_name] = pest_num
        else:
            for result in indentify_result.split("#"):
                tuple_result = result.split(",")
                pest_name = insect_dict.get(tuple_result[0],"未命名")
                pest_num = int(tuple_result[1])
                if pest_name in pest_day_info:
                    pest_day_info[pest_name]["sum"] += pest_num
                else:
                    pest_day_info[pest_name] = {"addtime":date_stamp,"sum":pest_num}
                if pest_name in pest_info_total:
                    pest_info_total[pest_name] += pest_num
                else:
                    pest_info_total[pest_name] = pest_num
    # 最后一天的数据统计,循环内加不了
    for pest_day_key,pest_day_value in pest_day_info.items():
        if pest_day_key in chart_info:
            chart_info[pest_day_key].append(pest_day_value)
        else:
            chart_info[pest_day_key] = []
            chart_info[pest_day_key].append(pest_day_value)
    if len(d_id_list) == 1: # 单台设备可以来获取温湿度,多台设备不能获取温湿度
        if time_recording != 0:
            at_avg = int(sum(at_day_info)//len(at_day_info)) if len(at_day_info)!=0 else 25
            ah_avg = int(sum(ah_day_info)//len(ah_day_info)) if len(ah_day_info)!=0 else 30
            at_ah_info.append({"addtime":time_recording,"at":at_avg,"ah":ah_avg})
    # 字典排序
    pest_info_total = dict(sorted(pest_info_total.items(),key=lambda x:x[1],reverse=True))
    data = {"char_data":chart_info,"pest_total":pest_info_total}
    if len(d_id_list) == 1:
        data["at_ah_info"] = at_ah_info
    return data
        
    
@kedong_deco(login_required=True)
def pest_image_source(request):
    """
    害虫统计页面
    害虫溯源图片接口
    参数:
    d_ids                   必传                            设备自增ID
    identify_model          必传                            识别模型('A'为识别模型A,'B'为识别模型B)
    amend                   必传                            机器'0'或者人为'1',不传默认为'0'机器识别
    start_time              必传(string 秒级时间戳)          开始时间    (用于时间搜索)
    end_time                必传(string 秒级时间戳)          结束时间    (用于时间所有)
    pest_name               非必传                          用于筛选项,有则查,无则全部,害虫名字
    page                    非必传                          页码 不传默认为1
    page_size               非必传                          数据条数 默认为10

    返回值:
    data": {
        "pest_image_data": [
            {
                "deviceId": "862285038174052",
                "deviceName": "测报灯",
                "pestName": "蓝目天蛾、黑绒绢金龟、瓢虫",
                "addtime": 1658246342,
                "location": "云南省昆明市呈贡区",
                "img_url": "https://bigdata-all.oss-cn-beijing.aliyuncs.com/Basics/cbd/620210630173657/2022/1/7/30.jpg",
                "indentify_photo": "http://bigdata-all.oss-accelerate.aliyuncs.com/Result/cbd/620210630173657/2022/1/7/30.jpg",
                "pest_dict": {
                    "蓝目天蛾": "1",
                    "黑绒绢金龟": "1",
                    "瓢虫": "1"
                }
            }
        ],
        "total_count": 1,
        "current_count": 1
    }
    """
    parameters = request.POST
    d_ids = parameters.get("d_ids")
    
    start_time = int(parameters.get("start_time"))
    end_time = int(parameters.get("end_time"))
    select_name = parameters.get("pest_name")
    page = int(parameters.get("page","1"))
    page_size = int(parameters.get("page_size","10"))
    amend = parameters.get("amend","0")

    
    # 获取统计设备列表
    if d_ids:
        d_id_list = [int(d_id) for d_id in d_ids.split(",")]
        d_id_dicts = {}
        device_queryset = MongoDevice.objects.filter(id__in=d_id_list)
        for device_object in device_queryset:
            d_id_dicts[device_object.id] = {"location":device_object.province+device_object.city+device_object.district,
                                            "device_id":device_object.device_id,
                                            "device_code":device_object.device_code,
                                            "device_name":device_object.device_name if device_object.device_name else "测报灯"
                                            }
    else:
        raise PortError("d_ids","参数缺失")
    
    # 统计
    photo_queryset = MongoCBDphoto.objects.filter(device_id__in=list(d_id_dicts.keys()),photo_status=1,addtime__range=(start_time,end_time))
    if amend == "0":
        photo_queryset = photo_queryset.filter(~Q(indentify_result="")).order_by("-addtime")
    else:
        photo_queryset = photo_queryset.filter(~Q(indentify_result="") | ~Q(mark="")).order_by("-addtime")
    
    pest_image_data = []
    for photo_object in photo_queryset:
        # 单张照片结果
        indentify_result = photo_object.indentify_result
        mark = photo_object.mark
        pest_string = ""
        pest_dict = {}
        if amend == "1" and mark:
            if mark == "[]":
                continue
            else:
                mark = json.loads(mark)
                for index,label in enumerate(mark):
                    pest_name = label.get("text")
                    pest_num = 1
                    if pest_name not in pest_string:
                        if index != 0:
                            pest_string += "、"
                        pest_string += pest_name
                        
                    if pest_name in pest_dict:
                        pest_dict[pest_name] += pest_num
                    else:
                        pest_dict[pest_name] = 1
        else:
            for index,result in enumerate(indentify_result.split("#")) :
                if index != 0:
                    pest_string += "、"
                tuple_result = result.split(",")
                pest_name = insect_dict.get(tuple_result[0],"未命名")
                pest_string+=pest_name
                pest_dict[pest_name] = int(tuple_result[1])
        if select_name and select_name not in pest_string:
            continue
        addtime = photo_object.addtime
        __d_id = int(photo_object.device_id)
        device_code = d_id_dicts[__d_id]["device_code"]
        
        pest_image_data.append({"deviceId":d_id_dicts[__d_id]["device_id"],
                                "deviceName":d_id_dicts[__d_id]["device_name"],
                                "pestName":pest_string,
                                "addtime":addtime,
                                "location":d_id_dicts[__d_id]["location"],
                                "img_url":photo_object.addr,
                                "indentify_photo":photo_object.indentify_photo,
                                "pest_dict":pest_dict
        })
    return_data = pest_image_data[(page-1)*page_size:page*page_size]

    return {"pest_image_data":return_data,"total_count":len(pest_image_data),"current_count":len(return_data)}


@kedong_deco(login_required=True)
def pest_base_data(request):
    """
    害虫统计页面
    虫害基础数据接口
    参数:
    d_id                    必传                            设备自增ID
    identify_model          必传                            识别模型('A'为识别模型A,'B'为识别模型B)
    amend                   必传                            机器'0'或者人为'1',不传默认为'0'机器识别
    start_time              必传(string 秒级时间戳)          开始时间    (用于时间搜索)
    end_time                必传(string 秒级时间戳)          结束时间    (用于时间所有)
    pest_name               非必传                          用于筛选项,有则查,无则全部,害虫名字
    page                    非必传                          页码 不传默认为1
    page_size               非必传                          数据条数 默认为10

    返回值:
    "data": {
        "pest_image_data": [
            {
                "pest_name": "瓢虫",
                "pest_num": 1,
                "addtime": 1658246342
            }
        ],
        "total_count": 1,
        "current_count": 1
    }
    """
    parameters = request.POST
    d_ids = parameters.get("d_ids")
    start_time = int(parameters.get("start_time"))
    end_time = int(parameters.get("end_time"))
    select_name = parameters.get("pest_name")
    page = int(parameters.get("page","1"))
    page_size = int(parameters.get("page_size",10))
    amend = parameters.get("amend","0")
    
    # 获取统计设备列表
    if d_ids:
        d_id_list = [int(d_id) for d_id in d_ids.split(",")]
    else:
        raise PortError("d_ids","参数缺失")
    
    # 统计
    photo_queryset = MongoCBDphoto.objects.filter(device_id__in=d_id_list,photo_status=1,addtime__range=(start_time,end_time))
    if amend == "0":
        photo_queryset = photo_queryset.filter(~Q(indentify_result="")).order_by("-addtime")
    else:
        photo_queryset = photo_queryset.filter(~Q(indentify_result="") | ~Q(mark="")).order_by("-addtime")
    
    pest_base_data = []
    for photo_object in photo_queryset:
        # 单张照片结果
        indentify_result = photo_object.indentify_result
        mark = photo_object.mark
        addtime = photo_object.addtime
        pest_dict = {}
        if amend == "1" and mark:
            mark = json.loads(mark)
            for label in mark:
                pest_name = label.get("text")
                pest_num = 1
                if select_name and select_name not in pest_name:
                    continue
                if pest_name in pest_dict:
                    pest_dict[pest_name] += pest_num
                else:
                    pest_dict[pest_name] = pest_num
            for label_key,label_value in pest_dict.items():
                pest_base_data.append(dict(pest_name=label_key,pest_num=label_value,addtime=addtime))
        else:
            for result in indentify_result.split("#"):
                tuple_result = result.split(",")
                pest_name = insect_dict.get(tuple_result[0],"未命名")
                if select_name and select_name not in pest_name:
                    continue
                pest_num = int(tuple_result[1])
                pest_dict=dict(pest_name=pest_name,pest_num=pest_num,addtime=addtime)
                pest_base_data.append(pest_dict)
        
    return_data = pest_base_data[(page-1)*page_size:page*page_size]

    return {"pest_image_data":return_data,"total_count":len(pest_base_data),"current_count":len(return_data)}



def pest_enumeration(request):
    """
    虫情地图
    指定时间段内害虫列举接口

    参数:
    start_time                      必传(秒级时间戳)                        开始时间
    end_time                        必传(秒级时间戳)                        结束时间

    返回:
    {
        "data": ["杨二尾舟蛾","劳氏粘虫", ...]
    }
    """
    parameters = request.POST
    start_time = parameters.get("start_time")
    end_time = parameters.get("end_time")
    if start_time:
        start_time = int(start_time)
    else:
        raise PortError("start_time","参数缺失")
    if end_time:
        end_time = int(end_time)
    else:
        raise PortError("end_time","参数缺失")

    pest_cursor = Pest_distribute.objects.filter(uptime__gte=start_time, uptime__lte=end_time).values("pest_name")
    pest_name_lists = [pest_obj["pest_name"] for pest_obj in pest_cursor]

    return pest_name_lists

    

def pest_tendency(request):
    """
    虫情地图
    虫情趋势接口

    参数:
    pest_name                       必传(str)                              害虫名称
    req                             必传(str)                              筛选条件('start':始见期,'end':终见期,'focus':高峰期)
    start_time                      必传(秒级时间戳)                        开始时间
    end_time                        必传(秒级时间戳)                        结束时间

    返回:
    {
        "data": [
            {
                "province": "广东省",
                "city": "揭阳市",
                "uptime": 1659801600
            },
            {
                "province": "辽宁省",
                "city": "沈阳市",
                "uptime": 1659715200
            },
            ...
        ]
    }
    """
    parameters = request.POST
    pest_name = parameters.get("pest_name")
    start_time = parameters.get("start_time")
    end_time = parameters.get("end_time")
    if not pest_name:
        raise PortError("pest_name","参数缺失")
    if start_time:
        start_time = int(start_time)
    else:
        raise PortError("start_time","参数缺失")
    if end_time:
        end_time = int(end_time)
    else:
        raise PortError("end_time","参数缺失")
    req = parameters.get("req")
    if req == "start":
        req_sort = {"uptime": 1}
    elif req == "end":
        req_sort = {"uptime": -1}
    elif req == "focus":
        req_sort = {"avg_num": -1}
    else:
        raise PortError("req","参数异常")

    pest_cursor = Pest_distribute.objects.filter(
        pest_name=pest_name, uptime__gte=start_time, uptime_lte=end_time).values(
        "province", "city").annotate(pest_count=Max("uptime")).values("province", "city", "uptime").order_by('-uptime')
    data = [pest_obj for pest_obj in pest_cursor]

    return data



def pest_distribution(request):
    """
    虫情地图
    虫情密度 地域分布接口

    参数:
    pest_name                       必传(str)                              害虫名称
    start_time                      必传(秒级时间戳)                        开始时间
    end_time                        必传(秒级时间戳)                        结束时间

    返回:
    {
        "data":[
            {
                "province": "江苏省",
                "city": "淮安市",
                "pest_count": 4.33
            },
            {
                "province": "四川省",
                "city": "达州市",
                "pest_count": 3.0
            },
            ...
        ]
    }
    """
    parameters = request.POST
    pest_name = parameters.get("pest_name")
    start_time = parameters.get("start_time")
    end_time = parameters.get("end_time")
    if not pest_name:
        raise PortError("pest_name","参数缺失")
    if start_time:
        start_time = int(start_time)
    else:
        raise PortError("start_time","参数缺失")
    if end_time:
        end_time = int(end_time)
    else:
        raise PortError("end_time","参数缺失")

    pest_cursor = Pest_distribute.objects.filter(
        pest_name=pest_name, uptime__gte=start_time, uptime_lte=end_time).values(
        "province", "city").annotate(pest_count=Sum("pest_count")).values(
        "province", "city", "pest_count")
    data = []
    for pest_obj in pest_cursor:
        pest_obj["pest_count"] = round(pest_obj["pest_count"],2)
        data.append(pest_obj)
    return data



def pest_statistics(request):
    """
    害虫统计页面
    害虫变化趋势折线图
    参数:
    d_id                    必传                           设备自增id
    start_time              非必传(string 时间戳)           开始时间    (用于时间搜索)
    end_time                非必传(string 时间戳)           结束时间    (用于时间搜索)
    pest_name               非必传(str)                     害虫名称
    返回值:
    "broken_line": [
             {
                "addtime": 1590230292,      时间
                "temperature": 39.8,        温度
                "humidity": 34.9,           湿度
                "_sums": 17                 这个时间点的害虫总数
                "_sname": 蛾子               害虫名字
            },
    "date":[                                害虫搜索出来的数据
            {
                "addtime": 1590230292,      时间
                "temperature": 39.8,        温度
                "humidity": 34.9,           湿度
                "_sums": 17                 这个时间点的害虫总数
                 "_sname": 蛾子               害虫名字
            },
    ],....]
    "device_name":"这里是设备名称",
    "address": "这里是设备位置",
    "disable":device.disable,    #0 不识别,1识别 2,计数
    """
    post_info = request.POST
    d_id = post_info.get("d_id")
    identify_model = post_info.get("identify_model")
    start_time = post_info.get("start_time")
    end_time = post_info.get("end_time")
    pest_name = post_info.get("pest_name","")
    if not d_id:
        raise PortError('device_id', "设备不能为空")
    device = MongoDevice.objects.get(id=d_id)
    province = device.province
    city = device.city
    district = device.district
    device_name = device.device_name

    myuser = request.myuser
    if not myuser.user_type == 1 and device.device_expire == "1":
        if identify_model == "B":
            cbdphotos = CBDphoto_B.objects.filter(~Q(indentify_photo=None),device_id=d_id,photo_status=1,addtime__lte=int(device.device_expire_time)).order_by('-addtime')
        else:
            cbdphotos = MongoCBDphoto.objects.filter(~Q(indentify_photo=None),device_id=d_id,photo_status=1,addtime__lte=int(device.device_expire_time)).order_by('-addtime')
        if end_time and int(end_time) > int(device.device_expire_time):
            end_time = device.device_expire_time
            cbdphotos = cbdphotos.filter(addtime__range=(int(start_time),int(end_time)))
    else:
        if identify_model == "B":
            cbdphotos = CBDphoto_B.objects.filter(~Q(indentify_photo=None),device_id=d_id,photo_status=1).order_by('-addtime')
        else:
            cbdphotos = MongoCBDphoto.objects.filter(~Q(indentify_photo=None),device_id=d_id,photo_status=1).order_by('-addtime')
        if start_time:
            cbdphotos = cbdphotos.filter(addtime__gte=int(start_time))
        if end_time:
            cbdphotos = cbdphotos.filter(addtime__lte=int(end_time))
    page = post_info.get('page',1)
    if page:
        page = int(page)
    page_size = post_info.get('page_size')
    start = ''
    end = ''
    if page_size:
        page_size = int(page_size)
    if page and page_size:
        start = max((page - 1), 0) * page_size
        end = page * page_size
    date = []
    d_sums = {}
    indentify_photos = {}
    percentage = []
    counts = ''
    time_d_sums = []
    nums = 0
    nusm = 0
    for c in cbdphotos:
        photo_id = c.id
        indentify_photo = c.indentify_photo
        if not indentify_photo:
            continue
        if not indentify_photo.startswith('http'):
            if str(indentify_photo).startswith('/'):
                indentify_photo = config_dict['image_url']["discern"] + indentify_photo
            else:
                indentify_photo = config_dict['image_url']["discern"] + "/" + indentify_photo

        if not pest_name:
            time_d_sums.append({"pest": c.indentify_result,
                                "addtime": c.addtime,
                                "result_photo":indentify_photo,
                                "mark":c.mark,
                                })
        if c.indentify_result != None and c.indentify_result != "":
            sums = c.indentify_result.split('#')
            for i in sums:
                i_result = i.split(',')
                if pest_name == insect_dict[i_result[0]]:
                    date.append({
                        "temperature": c.at,
                        "humidity": c.ah,
                        "addtime": c.addtime,
                        "_sums": i_result[1],
                        "_sname":insect_dict[i_result[0]],
                        })
                
                if not pest_name:
                    _result = sums[0].split(',')
                    date.append({
                        "temperature": c.at,
                        "humidity": c.ah,
                        "addtime": c.addtime,
                        "_sums": _result[1],
                        "_sname": insect_dict[_result[0]]})
                    
                    nums += int(_result[1])
                    d_sums.setdefault(i_result[0], []).append(int(i_result[1]))
                    indentify_photos.setdefault(i_result[0], []).append(photo_id)

            
        # 增加用户手动标注的数据
        # _nums = count + num

        if c.mark:
            mark = json.loads(c.mark)
            for y in mark:
                if  pest_name == y["tagName"]:
                    nusm += 1
                    date.append({
                        "temperature": c.at,
                        "humidity": c.ah,
                        "addtime": c.addtime,
                        "_sums": nusm,
                        "_sname":y["tagName"]})
                if not pest_name:
                    nusm += 1
                    date.append({
                        "temperature": c.at,
                        "humidity": c.ah,
                        "addtime": c.addtime,
                        "_sums": nusm,
                        "_sname":y["tagName"]})
                d_sums.setdefault(y["tagName"], []).append(1)
                indentify_photos.setdefault(y["tagName"], []).append(photo_id)

    user_type = request.myuser.user_type

    if user_type == 1:
        disable = 1
    else:
        disable = device.disable
    if not pest_name:
        # user_type = 
        if disable == 0:
            percentage = "设备不具备识别功能"
            raise PortError('device_id', "此设备不具备识别功能")
        elif disable == 1:
            for k,v in d_sums.items():
                try:
                    name_num = insect_dict[k]
                except:
                    name_num = k
                percentage.append({
                    "name_num":name_num,
                    "sum": sum(v),
                    "indentify_photos":indentify_photos[k],
                    "num":k})
            #percentage = [{"name_num": insect_dict[k], "sum": sum(v),"indentify_photos":indentify_photos[k],"num":k} for k, v in d_sums.items()]
            counts = len(percentage)
            if start or end:
                percentage = percentage[start:end]
                time_d_sums = time_d_sums[start:end]
        elif  disable == 2:
            percentage = nums
            if start or end:
                time_d_sums = time_d_sums[start:end]
    data = {
        "disable":disable, #0 不识别,1识别 2,计数
        "percentage":percentage,  # 统计
        "time_d_sums":time_d_sums,  # 时间详细
        "device_name":device_name,
        "address": province + city + district,
        "counts":counts,
        "date":date,  #饼状图
    }
    return data


# import copy
import operator

def pest_statistics_total(request):
    """
    害虫统计页面
    害虫变化趋势折线图
    参数:
    start_time              非必传(string 时间戳)           开始时间    (用于时间搜索)
    end_time                非必传(string 时间戳)           结束时间    (用于时间搜索)
    pest_name               非必传(str)                     害虫名称
    返回值:
    "broken_line": [
             {
                "addtime": 1590230292,      时间
                "at": 39.8,        温度
                "ah": 34.9,           湿度
                "_sums": 17                 这个时间点的害虫总数
                "_sname": 蛾子               害虫名字
            },
    "date":[                                害虫搜索出来的数据
            {
                "addtime": 1590230292,      时间
                "at": 39.8,        温度
                "ah": 34.9,           湿度
                "_sums": 17                 这个时间点的害虫总数
                 "_sname": 蛾子               害虫名字
            },
    ],....]
    "device_name":"这里是设备名称",
    "address": "这里是设备位置",
    """
    post_info = request.POST
    start_time = post_info.get("start_time")
    end_time = post_info.get("end_time")
    pest_name = post_info.get("pest_name","")
    myuser = request.myuser
    devices = MongoDevice.devices(uid=myuser.uid,myuser=myuser)
    if myuser.user_type != 4 or myuser.user_type != 1:
        devices = devices.filter(disable=1)
    #自动统计
    date = []
    d_sums = {}
    percentage = []
    time_d_sums = []
    counts = ""
    for i in devices:
        if not myuser.user_type == 1 and i.device_expire == "1":
            cbd_data = MongoCBDphoto.objects.filter(~Q(indentify_photo=None),device_id=i.id,photo_status=1,addtime__lte=int(i.device_expire_time)).order_by('-id')
            if end_time and int(end_time) > int(i.device_expire_time):
                end_time = i.device_expire_time
                cbd_data = cbd_data.filter(addtime__range=(int(start_time),int(end_time)))
        else:
            cbd_data = MongoCBDphoto.objects.filter(~Q(indentify_photo=None),device_id=i.id,photo_status=1).order_by('-id')
            if start_time:
                cbd_data = cbd_data.filter(addtime__range=(int(start_time),int(end_time)))

        page = post_info.get('page',1)
        if page:
            page = int(page)
        page_size = post_info.get('page_size')
        start = ''
        end = ''
        if page_size:
            page_size = int(page_size)
        if page and page_size:
            start = max((page - 1), 0) * page_size
            end = page * page_size
        
        counts = ''
        for c in cbd_data:
            indentify_photo = c.indentify_photo
            if not indentify_photo:
                continue
            if not indentify_photo.startswith('http'):
                if str(indentify_photo).startswith('/'):
                    indentify_photo = config_dict['image_url']["discern"] + indentify_photo
                else:
                    indentify_photo = config_dict['image_url']["discern"] + "/" + indentify_photo
            if not pest_name:
                time_d_sums.append({"pest": c.indentify_result,
                                    "addtime": c.addtime,
                                    "result_photo":indentify_photo,
                                    })
            if c.indentify_result != None and c.indentify_result != "":
                sums = c.indentify_result.split('#')
                for i in sums:
                    i_result = i.split(',')
                    if pest_name == insect_dict[i_result[0]]:
                            date.append({
                            "temperature": c.at,
                            "humidity": c.ah,
                            "addtime": c.addtime,
                            "_sums": i_result[1],
                            "_sname":insect_dict[i_result[0]],
                        })
                    if not pest_name:
                        _result = sums[0].split(',')
                        date.append({
                            "temperature": c.at,
                            "humidity": c.ah,
                            "addtime": c.addtime,
                            "_sums": int(_result[1]),
                            "_sname": insect_dict[_result[0]],
                        })
                        d_sums.setdefault(i_result[0], []).append(int(i_result[1]))
        if not pest_name:
            percentage = [{"name_num": insect_dict[k], "sum": sum(v),"num":k} for k, v in d_sums.items()]
            counts = len(percentage)
            if start or end:
                percentage = percentage[start:end]
                time_d_sums = time_d_sums[start:end]
    data = {}
    if pest_name:
        for item in date:
            add_time, _sums, _sname,at,ah = item['addtime'], item['_sums'], item['_sname'],item["temperature"],item["humidity"]
            key = '{}_{}_{}_{}'.format(add_time, _sname,at,ah)
            if key in data:
                data[key] += _sums
            else:
                data[key] = _sums
        result = []
        for key, value in data.items():
            add_time, _sname,at,ah= key.split('_')
            result.append({
                "addtime": add_time,
                "_sums": data[key],
                "_sname": _sname,
                "at" : at,
                "ah": ah
            })
    else:
        for item in date:
            add_time, _sums, _sname, at, ah = item['addtime'], item['_sums'], item['_sname'],item["temperature"],item["humidity"]
            key = '{}_{}_{}_{}'.format(_sname,add_time,at,ah)
            if key in data:
                data[key] += _sums
            else:
                data[key] = _sums
        result = []
        for key, value in data.items():
            _sname,add_time,at,ah= key.split('_')
            result.append({
                "addtime": add_time,
                "_sums": data[key],
                "_sname": _sname,
                "at" : at,
                "ah": ah
            })
    # 降序
    # list2 = sorted(result, key=operator.itemgetter('addtime'),reverse=True)
    list2 = sorted(result, key=operator.itemgetter('addtime'))
    data = {
        "percentage":percentage,  # 统计
        "time_d_sums":time_d_sums,  # 时间详细
        # "address": province + city + district,
        "counts":counts,
        "date":list2,  #饼状图
    }
    return data



def pest_contrast_total(request):
    """
    某一害虫对比
    参数:
    d_id                    必传(str)                      设备id
    start_time              非必传(string 时间戳)           开始时间    (用于时间搜索)
    end_time                非必传(string 时间戳)           结束时间    (用于时间搜索)
    pest_name               非必传(str)                     害虫名称
    返回值:
    """
    post_info = request.POST
    start_time = post_info.get("start_time")
    identify_model = post_info.get("identify_model")
    end_time = post_info.get("end_time")
    pest_name = post_info.get("pest_name","")
    d_id = post_info.get("d_id")

    if not d_id:
        raise PortError('device_id', "设备不能为空")
    
    device = Device.objects.get(id=d_id)
    
    myuser = request.myuser
    if not myuser.user_type == 1 and device.device_expire == "1":
        if identify_model == "B":
            cbd_data = CBDphoto_B.objects.filter(~Q(indentify_photo=None),device_id=device.id,photo_status=1,addtime__lte=int(device.device_expire_time)).order_by("-id")
        else:
            cbd_data = CBDphoto.objects.filter(~Q(indentify_photo=None),device_id=device.id,photo_status=1,addtime__lte=int(device.device_expire_time)).order_by("-id")
        if end_time and int(end_time) > int(device.device_expire_time):
            end_time = device.device_expire_time
            cbd_data = cbd_data.filter(addtime__range=(int(start_time),int(end_time)))
    else:
        if identify_model == "B":
            cbd_data = CBDphoto_B.objects.filter(~Q(indentify_photo=None),device_id=device.id,photo_status=1).order_by("-id")
        else:
            cbd_data = CBDphoto.objects.filter(~Q(indentify_photo=None),device_id=device.id,photo_status=1).order_by("-id")
        if start_time:
            cbd_data = cbd_data.filter(addtime__range=(int(start_time),int(end_time)))

    
    # cbdphotos = CBDphoto.objects.filter(~Q(indentify_photo=None),device_id=d_id).order_by('-id')
    # if start_time:
    #     cbdphotos = cbdphotos.filter(addtime__gte=int(start_time))
    # if end_time:
    #     cbdphotos = cbdphotos.filter(addtime__lte=int(end_time))
    date = []
    d_sums = {}
    indentify_photos = {}
    percentage = []
    for c in cbd_data:
        photo_id = c.id
        indentify_photo = c.indentify_photo
        if not indentify_photo:
            continue
        elif not c.indentify_result:
            continue
        sums = c.indentify_result.split('#')
        for i in sums:
            i_result = i.split(',')
            if pest_name == insect_dict[i_result[0]]:
                    date.append({
                    "temperature": c.at,
                    "humidity": c.ah,
                    "addtime": c.addtime,
                    "_sums": i_result[1],
                    "_sname":insect_dict[i_result[0]],
                })
            if not pest_name:
                date.append({
                    "temperature": c.at,
                    "humidity": c.ah,
                    "addtime": c.addtime,
                    "_sums": int(i_result[1]),
                    "_sname": insect_dict[i_result[0]],
                })
                d_sums.setdefault(i_result[0], []).append(int(i_result[1]))
                indentify_photos.setdefault(i_result[0], []).append(photo_id)
    if not pest_name:
        percentage = [{"name_num": insect_dict[k], "sum": sum(v),"indentify_photos":indentify_photos[k],"num":k} for k, v in d_sums.items()]
    data = {}
    if pest_name:
        for item in date:
            add_time, _sums, _sname,at,ah = item['addtime'], item['_sums'], item['_sname'],item["temperature"],item["humidity"]
            key = '{}_{}_{}_{}'.format(add_time, _sname,at,ah)
            if key in data:
                data[key] += _sums
            else:
                data[key] = _sums
        result = []
        for key, value in data.items():
            add_time, _sname,at,ah= key.split('_')
            result.append({
                "addtime": add_time,
                "_sums": data[key],
                "_sname": _sname,
                "at" : at,
                "ah": ah
            })
    else:
        for item in date:
            add_time, _sums, _sname, at, ah = item['addtime'], item['_sums'], item['_sname'],item["temperature"],item["humidity"]
            key = '{}_{}_{}_{}'.format(_sname,add_time,at,ah)
            if key in data:
                data[key] += _sums
            else:
                data[key] = _sums
        result = []
        for key, value in data.items():
            _sname,add_time,at,ah= key.split('_')
            result.append({
                "addtime": add_time,
                "_sums": data[key],
                "_sname": _sname,
                "at" : at,
                "ah": ah
            })
    # 降序
    # list2 = sorted(result, key=operator.itemgetter('addtime'),reverse=True)
    list2 = sorted(result, key=operator.itemgetter('addtime'))
    data = {
        "percentage":percentage,
        "list2":list2
    }
    return data


def photo_result(request):
    """
    害虫统计页面
    害虫变化趋势折线图
    参数:
    photo_ids                    必传                           照片自增id
    """
    post_info = request.POST
    photo_ids = post_info.get("photo_ids","")
    if not photo_ids:
        raise PortError('photo_ids', "不能为空")
    photo_ids = [int(i) for i in eval(photo_ids)]
    cbdphotos = MongoCBDphoto.objects.filter(id__in=photo_ids).order_by('-id')
    data = []
    for p in cbdphotos:
        indentify_photo = p.indentify_photo
        if not indentify_photo.startswith('http'):
            if str(indentify_photo).startswith('/'):
                indentify_photo = config_dict['image_url']["discern"] + indentify_photo
            else:
                indentify_photo = config_dict['image_url']["discern"] + "/" + indentify_photo
        data.append(
            {
                "indentify_photo":indentify_photo,
                "indentify_result":p.indentify_result,
            }
        )
    return data



def pest_manual_statistics(request):
    """
    病虫害手动统计接口/害虫名称搜索:
    参数:
    device_id                   必传(str)                          设备id
    start_time                  非必传(时间戳)                      开始时间
    end_time                    非必传(时间戳)                      结束时间
    pest_name                   非必传(str)                         害虫名
    """
    device_id = request.POST.get('device_id')
    start_time = request.POST.get("start_time")
    end_time = request.POST.get("end_time")
    pest_name = request.POST.get("pest_name")
    page = int(request.POST.get('page',1))
    try:
        device = MongoDevice.objects.get(id=device_id)
    except:
        raise PortError('device_id', "没有该设备")
    
    if not device_id:
        raise PortError('device_id', "没有传设备号")

    myuser = request.myuser
    if not myuser.user_type == 1 and device.device_expire == "1":
        cbdphotos = Device_Desc.objects.filter(device_id=device_id)
        if end_time and int(end_time) > int(device.device_expire_time):
            end_time = device.device_expire_time
            cbdphotos = cbdphotos.filter(addtime__range=(int(start_time),int(end_time)))
    else:
        cbdphotos = Device_Desc.objects.filter(device_id=device_id)
        if start_time:
            cbdphotos = cbdphotos.filter(add_time__gte=start_time)
        if end_time:
            cbdphotos = cbdphotos.filter(add_time__lte=end_time)

    dat = [] # 害虫名称
    data = [] # 饼状图
    date = [] # 列表
    pest = [] # 折线图
    if cbdphotos:
        for i in cbdphotos:
            cbd_img_list = MongoCBDphoto.objects.filter(id=i.photo_id)
            pest_num = 0
            if i.pest_name not in dat:
                dat.append(i.pest_name)
                pest_list = cbdphotos.filter(pest_name=i.pest_name)
                for y in pest_list:
                    pest_num += int(y.pest_num)
                data.append({"pest_name":i.pest_name,"pest_num":pest_num})
            image = ""
            for x in cbd_img_list:
                image = x.addr
            if image.startswith("http"):
                image = image
            else:
                image = config_dict["image_url"]["frond"] + image
            date.append({
                "pest_num":i.pest_num,
                "pest_name":i.pest_name,
                "crop_name":i.crop_name,
                "pest_case":i.pest_case,
                "add_time":i.add_time,
                "image":image
            })
        dat_list = date[(10*(page-1)):(page*10)]
    else:
        dat_list = []
    if dat:
        if pest_name:
            pest_list = cbdphotos.filter(pest_name=pest_name)
        else:
            pest_list = cbdphotos.filter(pest_name=dat[0])
            pest_name = dat[0]
        for ii in pest_list:
            pests = {"pest_name":pest_name}
            if pest_name == ii.pest_name:
                pest.append({
                "pest_num":ii.pest_num,
                "add_time":ii.add_time})
            pests["pest_list"] = pest
    else:
        pests = {}
    nums = cbdphotos.count()
    data = {"nums":nums,"dat":data,"date":dat_list,"pests":pests}
    return data


from django.db.models import Q
import time
import pymysql


# 已弃用
# @kedong_deco(login_required=True)
def worm_list(request):
    """
    害虫列表
    参数；
    暂无
    返回值:
    "data": [
        {
            "name": "暗纹紫褐螟",
            "num": "317"
        },....
        ]

    """
    insect_dict = ""
    try:
        dir_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))))
        path = os.path.join(dir_path, "scripts/pest_dict.json")
        with open(path,'r',encoding='utf-8') as f:
            insect_dict = json.loads(f.read())
    except Exception as e:
        path = sys.path[0]  + "/scripts/pest_dict.json" 
        with open(path,'r',encoding='utf-8') as f:
            insect_dict = json.loads(f.read())
    return insect_dict


@kedong_deco(login_required=True)
def cbd_pest_warning(request):
    """
    测报灯-害虫预警
    2022-05-19 14:22 csx
    参数:
    page            非必传(num)                     页码,默认为1
    page_size       非必传(num)                     每页数量,默认为10
    status          非必传(str)                     为yes时 是设置一键已读
    d_id            非必传(str)                     传id时,为单个数据设置已读
    device_id       非必传(str)                     传设备号时,为当前设备的预警信息
    返回值:
    {
    "errorCode": 0,
    "message": "",
    "formError": {},
    "data": {
        "data": [
            {
                "device_id": "862167051501330",                         设备号
                "warning_content": 4,                                   害虫种类数
                "warning_status": "1",                                  1目标种类预警 2、指定害虫数量预警  3 害虫数量总和预警 4综合预警
                "upltime": 1652936123,                                  时间戳
                "status": 0                                             0未读 1已读
            },
            {
                "device_id": "862167051501330",
                "warning_content": 411,
                "warning_status": "3",
                "upltime": 1652936123,
                "status": 0
            },
            {
                "device_id": "862167051501330",
                "warning_content": {
                    "铜绿丽金龟": "1头",
                    "水龟虫": "48头",
                    "龙虱": "4头",
                    "负子蝽": "13头"
                },
                "warning_status": "4",
                "upltime": 1652936123,
                "status": 0
            },

    """
    page = request.POST.get('page',1)
    page_size = request.POST.get('page_size',10)
    status = request.POST.get('status')
    d_id = request.POST.get('d_id')
    deviceid = request.POST.get("device_id")
    devices = MongoDevice.objects.filter(device_type_id=3)
    if deviceid:
        devices = devices.filter(device_id__icontains=deviceid)
    devices = devices.values("device_id")

    device_list = [d['device_id'] for d in devices]

    if page and page_size:
        page_size = int(page_size)
        page = int(page)
        start = max((page - 1), 0) * page_size
        end = page * page_size
    pest_warn = DevicePestWarning.objects.filter(device_id__in=device_list)
    if d_id:
        pest_warn = DevicePestWarning.objects.filter(id=d_id).update(status=1)
        return True

    data = []
    nums = pest_warn.count()

    if nums:
        if status:
            if status == "yes":
                pest_warn.update(status=1)
                return True
            else:
                raise PortError('',"参数错误")
        for x in pest_warn.order_by("-id")[start:end]:
            data.append({
                "d_id":x.id,
                "device_id":x.device_id,
                "warning_content":eval(x.warning_content),
                "warning_status":x.warning_status,
                "upltime":x.upltime,
                "status":x.status
            })

    return {"data":data,"nusm":nums}
    

@kedong_deco(login_required=True)
def qxz_warning(request):
    """ 
    气象站-通道要素预警
    2022-05-20 10:22 csx
    
    参数:
    page            非必传(num)                     页码,默认为1
    page_size       非必传(num)                     每页数量,默认为10
    
    status          非必传(str)                     为yes时 是设置一键已读
    
    d_id            非必传(str)                     传id时,为单个数据设置已读
    
    
    返回值:
    {
	"errorCode": 0,
	"message": "",
	"formError": {},
	"data": {
		"data": [
			{
				"d_id": 1,                                          数据id
				"device_id": "866193059770251",                     设备号
				"warning_content": "大于预警",                      预警描述
				"ekey": "空气温度#℃",                              要素描述 加单位
				"set_value": "13",                                  用户设置预警值
				"current_value": "19.3",                            设备当前上传的数据值
				"upltime": 1653012464,                              保存时间
				"status": 0                                         0 未读 1已读
			},
			{
				"d_id": 2,
				"device_id": "866193059770251",
				"warning_content": "大于预警",
				"ekey": "空气温度#℃",
				"set_value": "13",
				"current_value": "19.3",
				"upltime": 1653012757,
				"status": 0
			},
    
    """


    page = request.POST.get('page','1')
    page_size = request.POST.get('page_size','10')
    
    status = request.POST.get('status')
    device_type = request.POST.get('device_type',"5")
    d_id = request.POST.get('d_id')
    
    if device_type not in ("5","8"):
        raise PortError("","设备类型超出")
    

    if d_id:
        warn = QXZThresholdWarning.objects.filter(id=d_id).update(status=1)
        return True
    
    devices = MongoDevice.objects.filter(device_type_id=device_type)
    
    device_list = [device_id.device_id for device_id in devices]


    if page and page_size:
        if not page.isdigit() and not page_size.isdigit():
            raise PortError("","参数错误")
        page_size = int(page_size)
        page = int(page)
        
    else:
        page = 1 
        page_size = 10
        
    start = max((page - 1), 0) * page_size
    end = page * page_size
    warn = QXZThresholdWarning.objects.filter(device_id__in=device_list)
    
    
    
    data = []
    nums = warn.count()
    if nums:
        if status:
            if status == "yes":
                warn.update(status=1)
                return True
            else:
                raise PortError('',"参数错误")
        for x in warn.order_by("-id")[start:end]:
            data.append({
                "d_id":x.id,
                "device_id":x.device_id,
                "warning_content":x.warning_content,
                "ekey":x.ekey,
                "set_value":x.set_value,
                "current_value":x.current_value,
                "upltime":x.upltime,
                "status":x.status
            })
            

    return {"data":data,"nusm":nums}


@kedong_deco(login_required=True)
def xycb_pest_chart(request):
    """
    性诱1.0,3.0设备害虫折线图
    参数：
    d_id                    必传                                 设备id
    start_time              必传(string 秒级时间戳)               开始时间
    end_time                必传(string 秒级时间戳)               结束时间
    device_type_id          必传                                 设备类型编号 4性诱测报1.0, 8性诱测报3.0

    return
    {
    "total_num": 0,
    "pest_data": [
        {
            "pest_num": 0,
            "addtime": 1659024000
        },
        ]
    }
    """
    post_info = request.POST
    start_time = post_info.get('start_time')
    end_time = post_info.get('end_time')
    d_id = post_info.get("d_id")
    device_type_id = post_info.get("device_type_id")
    if d_id:
        d_id = int(d_id)
    else:
        raise PortError('d_id', "请输入设备id")
    if device_type_id:
        device_type_id = int(device_type_id)
    else:
        raise PortError("device_type_id", "请输入设备类型编号")
    if start_time:
        start_time = int(start_time)
    else:
        raise PortError('start_time', "请输入设备start_time")
    if end_time:
        end_time = int(end_time)
    else:
        raise PortError('end_time', "请输入设备end_time")
    try:
        device = MongoDevice.objects.get(id=d_id)
        device_expire = device.device_expire
        device_expire_time = device.device_expire_time
    except:
        raise PortError('device_id', "暂无此设备")

    myuser_type = request.myuser.user_type
    if not myuser_type == 1 and not myuser_type == 5 and device_expire == "1":
        if end_time > int(device_expire_time):
            end_time = int(device_expire_time)
    if end_time < start_time:
        raise PortError("expire time", "设备已到期")

    queryset = MongoXYCBData.objects.filter(device_id=d_id, addtime__gte=start_time, addtime__lte=end_time).order_by('-addtime')
    pest_data = []
    total_pest_num = 0
    for item in queryset:
        device_data = json.loads(item.device_data)
        try:
            infr_ct = device_data['infr_ct']
            addtime = item.addtime
            pest_data.append({
                "pest_num": infr_ct,
                "addtime": addtime
            })
            total_pest_num += infr_ct
        except Exception as e:
            continue

    return {"total_num": total_pest_num, "pest_data": pest_data}


@kedong_deco(login_required=True)
def set_decopy(request):
    """
    设置诱芯接口
    参数:
    device_type_id                  必传                        设备类型ID
    device_id                       必传                        设备编号
    decoy                           必传                        诱芯名称
    expire_time                     非必传                      诱芯过期时间
    """
    post_info = request.POST
    device_type_id = post_info.get("device_type_id")
    device_id = post_info.get("device_id")
    decoy = post_info.get("decoy")
    expire_time = post_info.get("expire_time")
    if not device_id:
        raise PortError("device_id","参数缺失")
    if not decoy:
        raise PortError("decoy","参数缺失")
    now_timestamp = int(time.time())
    if device_type_id == "4" or device_type_id == "8":
        try:
            device_object = MongoDevice.objects.get(device_id=device_id)
        except Exception as e:
            raise PortError("device_id","未查找到该设备")
        device_object.decoy = decoy
    else:
        raise PortError("device_type_id","参数缺失")
    device_object.xy_uptime = now_timestamp
    if expire_time:
        device_object.xy_expire_time = int(expire_time)
    device_object.save()
    return {"status":True}