package controllers

import (
	"fmt"
	"strconv"
	"time"

	validation "github.com/go-ozzo/ozzo-validation/v4"

	"github.com/astaxie/beego"

	"lc/common/models"
	"lc/common/util"
)

// 各种统计数据
const (
	DevStatusPrefix string = "dev_stat_"
	DevDataPrefix   string = "dev_data_"
	ONLINE          string = "online"
	TLast           string = "tlast"
	//TIME              string = "time"
)

type DataController struct {
	BaseController
}

// ReqHisData 历史数据
type ReqHisData struct {
	Code  string   `json:"code"` //设备编码
	Sids  []uint16 `json:"sids"` //SID编号
	Start string   `json:"start"`
	End   string   `json:"end"`
	Type  int      `json:"type"` //1:每小时数据；2:每天数据
}

// ReqBHisData 多设备历史数据
type ReqBHisData struct {
	Codes []string `json:"codes"` //设备编码
	Start string   `json:"start"`
	End   string   `json:"end"`
	Type  int      `json:"type"` //1:每小时数据；2:每天数据
}

type HisData struct {
	Time   util.MLTime `json:"time"`
	Val    float32     `json:"val"`
	ValMin float32     `json:"minval"`
	ValMax float32     `json:"maxval"`
}

type RespHisData struct {
	Code    string               `json:"code"` //设备编码
	MapData map[uint16][]HisData `json:"data"` //sid->数据
}

type RespBHisData struct {
	MapData map[string]map[uint16][]HisData `json:"data"` //sid->数据
}

// ReqRTData 实时数据
type ReqRTData struct {
	Codes []string `json:"codes"` //设备编码列表
}

type RTData struct {
	Time util.MLTime        `json:"time"`
	Data map[uint16]float32 `json:"data"`
}

type RTStatus struct {
	Online int         `json:"online"`
	Time   util.MLTime `json:"time"`
}

// ReqAlarmData 告警数据
type ReqAlarmData struct {
	Codes []string `json:"codes"` //设备编码
	Flag  int      `json:"flag"`  //0所有告警，1结束的告警，2未结束的告警
}
type RespAlarm struct {
	ID        int64       `json:"id"`
	DID       string      `json:"code"`
	TStart    util.MLTime `json:"tstart"`
	TEnd      util.MLTime `json:"tend,omitempty"`
	Content   string      `json:"content"`   //告警内容
	AlarmType uint16      `json:"alarmtype"` //告警类型
	Level     uint8       `json:"level"`     //告警等级,0:普通，1:重要，2:严重
	Threshold float32     `json:"threshold"`
	Value     float32     `json:"value"`
	Sid       uint16      `json:"sid"`       //sid，对应物模型的sid
	Cid       int         `json:"cid"`       //策略编号
	Cname     string      `json:"cname"`     //策略名称
	UpdatedAt util.MLTime `json:"updatedat"` //更新时间
}

// ReqEnergy 能耗数据
type ReqEnergy struct {
	Codes []string `json:"codes"`
	Start string   `json:"start"`
	End   string   `json:"end"`
	Flag  int      `json:"flag"` //1:每日数据；2:每月数据
}
type RespEnergy struct {
	Date       string  `json:"date"`
	Beginning  float32 `json:"beginning"`
	Ending     float32 `json:"ending"`
	Difference float32 `json:"difference"`
}

// ReqLightingRate 亮灯率数据
type ReqLightingRate struct {
	Tenant  string `json:"tenant"`
	Start   string `json:"start"`
	End     string `json:"end"`
	Quarter int    `json:"quarter"`
	Flag    int    `json:"flag"`
}

func (a ReqLightingRate) Validate() error {
	return validation.ValidateStruct(&a,
		validation.Field(&a.Tenant, validation.Required, validation.Length(4, 8)),
		validation.Field(&a.Start, validation.Required, validation.Date("2006-01-02")),
		validation.Field(&a.End, validation.Required, validation.Date("2006-01-02")),
		validation.Field(&a.Quarter, validation.In(0, 1, 2, 3, 4)),
		validation.Field(&a.Flag, validation.In(0, 1, 2, 3)),
	)
}

// ReqVehicleData 请求抓拍单元统计数据
type ReqVehicleData struct {
	Codes []string `json:"codes"`
	Start string   `json:"start"`
	End   string   `json:"end"`
	Types []int    `json:"types"`
	Flag  int      `json:"flag"`
}

func (a ReqVehicleData) Validate() error {
	return validation.ValidateStruct(&a,
		validation.Field(&a.Codes, validation.Length(1, 0)),
		validation.Field(&a.Start, validation.Required, validation.Date("2006-01-02 15:04:05")),
		validation.Field(&a.End, validation.Required, validation.Date("2006-01-02 15:04:05")),
		validation.Field(&a.Flag, validation.In(0, 1, 2, 3)),
	)
}

type DayLightingRateData struct {
	Date   string  `json:"date"`
	Total  int     `json:"total"`
	Number int     `json:"number"`
	Rate   float64 `json:"rate"`
}

type RespDayLightingRateData struct {
	Tenant string                `json:"tenant"`
	Flag   int                   `json:"flag"`
	Data   []DayLightingRateData `json:"data"`
}

type MonthLightingRate struct {
	Month string  `json:"month"`
	Rate  float64 `json:"rate"`
}

type RespMonthLightingRate struct {
	Tenant string              `json:"tenant"`
	Flag   int                 `json:"flag"`
	Data   []MonthLightingRate `json:"data"`
}

type QuarterLightingRate struct {
	Quarter string  `json:"quarter"`
	Rate    float64 `json:"rate"`
}

type RespQuarterLightingRate struct {
	Tenant string                `json:"tenant"`
	Flag   int                   `json:"flag"`
	Data   []QuarterLightingRate `json:"data"`
}

type YearLightingRate struct {
	Year string  `json:"year"`
	Rate float64 `json:"rate"`
}

type RespYearLightingRate struct {
	Tenant string             `json:"tenant"`
	Flag   int                `json:"flag"`
	Data   []YearLightingRate `json:"data"`
}

type ReqSosAlarm struct {
	Tenant string   `json:"tenant"`
	Start  string   `json:"start"`
	End    string   `json:"end"`
	Codes  []string `json:"codes"`
}

type RespSosAlarm struct {
	ID        int64       `json:"id"`
	DID       string      `json:"code"`
	TStart    util.MLTime `json:"tstart"`
	TEnd      util.MLTime `json:"tend,omitempty"`
	Duration  uint        `json:"duration"`
	UpdatedAt util.MLTime `json:"updatedat"` //更新时间
}

type ReqLampEvent struct {
	Tenant string   `json:"tenant"`
	Start  string   `json:"start"`
	End    string   `json:"end"`
	Codes  []string `json:"codes"`
}

type RespLampEvent struct {
	ID         int64       `json:"id"`
	DID        string      `json:"code"`
	TStart     util.MLTime `json:"tstart"`
	TEnd       util.MLTime `json:"tend,omitempty"`
	Brightness uint8       `json:"brightness"`
	Duration   uint        `json:"duration"`
	UpdatedAt  util.MLTime `json:"updatedat"` //更新时间
}

// ReqRadarDataList 雷达详细数据
type ReqRadarDataList struct {
	Codes []string `json:"codes"` //设备编码
	Start string   `json:"start"`
	End   string   `json:"end"`
	Model uint8    `json:"model"` //类型 0点目标 1车目标 所有目标2
}

type RadarData struct {
	Time  util.MLTime `json:"time"`
	Model uint8       `json:"model"`
	Speed float64     `json:"speed"`
	Dist  float64     `json:"dist"`
}

// ReqRadarSummaryData 雷达统计数据
type ReqRadarSummaryData struct {
	Codes []string `json:"codes"` //设备编码
	Start string   `json:"start"`
	End   string   `json:"end"`
	Type  uint8    `json:"type"`  //1：小时数据，每个网关、雷达每小时有一条数据2：日数据，每个网关、雷达每天有一条数据
	Model uint8    `json:"model"` //类型 0点目标 1车目标 所有目标2
}

type RadarSummaryData struct {
	Time            util.MLTime `json:"time"`
	Model           uint8       `json:"model"`
	OverSpeedNumber int         `json:"over_speed_number"`    // 超速数量
	Speed20Number   int         `json:"speed0_20_number"`     // 0-20 速度区间数量
	Speed40Number   int         `json:"speed20_40_number"`    // 20-40 速度区间数量
	Speed60Number   int         `json:"speed40_60_number"`    // 40-60 速度区间数量
	Speed80Number   int         `json:"speed60_80_number"`    // 60-80 速度区间数量
	Speed100Number  int         `json:"speed80_100_number"`   // 80-100 速度区间数量
	Speed120Number  int         `json:"speed100_120_number"`  // 100-120 速度区间数量
	SpeedMaxNumber  int         `json:"speed_over120_number"` // >120 速度区间数量
	Total           int         `json:"total"`
}

// History @Title 获取历史数据
// @Description 获取历史数据
// @Param body controllers.ReqHisData	true	"请求参数"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/history [post]
func (o *DataController) History() {
	var obj ReqHisData
	if err := json.Unmarshal(o.Ctx.Input.RequestBody, &obj); err != nil {
		//beego.Debug(string(o.Ctx.Input.RequestBody))
		//beego.Error(fmt.Sprintf("数据包解析错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("数据包解析错误:%s", err.Error()), nil)
		return
	}
	ret := RespHisData{
		Code:    obj.Code,
		MapData: make(map[uint16][]HisData),
	}
	if obj.Type == 1 {
		arr, err := models.GetDeviceHourData(obj.Code, obj.Start, obj.End, obj.Sids)
		if err != nil {
			o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
			return
		}
		for _, v := range arr {
			d := HisData{
				Time: util.MLTime(v.Time),
				Val:  v.Val,
			}
			ret.MapData[v.Sid] = append(ret.MapData[v.Sid], d)
		}
	} else if obj.Type == 2 {
		arr, err := models.GetDeviceDayData(obj.Code, obj.Start, obj.End, obj.Sids)
		if err != nil {
			o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
			return
		}
		for _, v := range arr {
			d := HisData{
				Time:   util.MLTime(v.Time),
				Val:    v.ValAvg,
				ValMin: v.ValMin,
				ValMax: v.ValMax,
			}
			ret.MapData[v.Sid] = append(ret.MapData[v.Sid], d)
		}
	}

	o.Response(Success, "成功", ret)
}

// BatchHistory @Title 获取多设备历史数据
// @Description 获取多设备历史数据
// @Param body controllers.ReqHisData	true	"请求参数"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/bhistory [post]
func (o *DataController) BatchHistory() {
	var obj ReqBHisData
	if err := json.Unmarshal(o.Ctx.Input.RequestBody, &obj); err != nil {
		//beego.Debug(string(o.Ctx.Input.RequestBody))
		//beego.Error(fmt.Sprintf("数据包解析错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("数据包解析错误:%s", err.Error()), nil)
		return
	}
	ret := RespBHisData{
		MapData: make(map[string]map[uint16][]HisData),
	}
	if obj.Type == 1 {
		arr, err := models.GetBDeviceHourData(obj.Codes, obj.Start, obj.End)
		if err != nil {
			o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
			return
		}
		for _, v := range arr {
			d := HisData{
				Time: util.MLTime(v.Time),
				Val:  v.Val,
			}
			if m, ok := ret.MapData[v.ID]; !ok {
				m = make(map[uint16][]HisData)
				m[v.Sid] = append(m[v.Sid], d)
				ret.MapData[v.ID] = m
			} else {
				m[v.Sid] = append(m[v.Sid], d)
			}
		}
	} else if obj.Type == 2 {
		arr, err := models.GetBDeviceDayData(obj.Codes, obj.Start, obj.End)
		if err != nil {
			o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
			return
		}
		for _, v := range arr {
			d := HisData{
				Time:   util.MLTime(v.Time),
				Val:    v.ValAvg,
				ValMin: v.ValMin,
				ValMax: v.ValMax,
			}
			if m, ok := ret.MapData[v.ID]; !ok {
				m = make(map[uint16][]HisData)
				m[v.Sid] = append(m[v.Sid], d)
				ret.MapData[v.ID] = m
			} else {
				m[v.Sid] = append(m[v.Sid], d)
			}
		}
	}

	o.Response(Success, "成功", ret)
}

// Realtime @Title 获取实时数据
// @Description 获取历史数据
// @Param body map[string]controllers.RTData	true	"请求参数"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/realtime [post]
func (o *DataController) Realtime() {
	var obj ReqRTData
	err := json.Unmarshal(o.Ctx.Input.RequestBody, &obj)
	if err != nil {
		beego.Debug(string(o.Ctx.Input.RequestBody))
		beego.Error(fmt.Sprintf("数据包解析错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("数据包解析错误:%s", err.Error()), nil)
		return
	}

	ret := make(map[string]*RTData)
	for _, v0 := range obj.Codes {
		var rtdata RTData
		rtdata.Data = make(map[uint16]float32)
		if mapdata, err := redisCltRawdata.HGetAll(DevDataPrefix + v0).Result(); err == nil {
			for k, v1 := range mapdata {
				if k == TIME {
					if t, err := util.MlParseTime(v1); err == nil {
						rtdata.Time = util.MLTime(t)
					}
				} else {
					if sid, err := strconv.Atoi(k); err == nil {
						if fval, err := strconv.ParseFloat(v1, 64); err == nil {
							rtdata.Data[uint16(sid)] = float32(fval)
						}
					}
				}
			}
			//时间和数据均有，则返回给调用方
			if !time.Time(rtdata.Time).IsZero() && len(rtdata.Data) > 0 {
				ret[v0] = &rtdata
			}
		}
	}
	o.Response(Success, "成功", ret)
}

// RealtimestatusGet @Title 获取实时状态
// @Description 获取实时状态
// @Param body controllers.ReqRTData	true	"请求参数"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/rtstatus [post]
func (o *DataController) RealtimestatusGet() {
	var obj ReqRTData
	err := json.Unmarshal(o.Ctx.Input.RequestBody, &obj)
	if err != nil {
		beego.Debug(string(o.Ctx.Input.RequestBody))
		beego.Error(fmt.Sprintf("数据包解析错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("数据包解析错误:%s", err.Error()), nil)
		return
	}

	ret := make(map[string]*RTStatus)
	for _, v0 := range obj.Codes {
		if mapdata, err := redisCltRawdata.HGetAll(DevStatusPrefix + v0).Result(); err == nil {
			var rtstatus RTStatus
			for k, v1 := range mapdata {
				if k == TLast {
					if t, err := util.MlParseTime(v1); err == nil {
						rtstatus.Time = util.MLTime(t)
					}
				} else if k == ONLINE {
					if n, err := strconv.Atoi(v1); err == nil {
						rtstatus.Online = n
					}
				}
			}
			ret[v0] = &rtstatus
		}
	}
	o.Response(Success, "成功", ret)
}

// AlarmSync @Title 同步告警数据
// @Description 同步告警数据
// @Param body body controllers.ReqAlarmData	true	"请求参数"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/alarm/sync [get]
func (o *DataController) AlarmSync() {
	id, _ := o.GetUint64("id")            //ID
	updatedat := o.GetString("updatedat") //更新时间
	arr, err := models.GetUpdateAlarm(id, updatedat)
	if err != nil {
		o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
		return
	}
	ret := make([]RespAlarm, 0, len(arr))
	for _, v := range arr {
		oo := RespAlarm{
			ID:        v.ID,
			DID:       v.DID,
			TStart:    util.MLTime(v.TStart),
			TEnd:      util.MLTime(v.TEnd),
			Content:   v.Content,
			AlarmType: v.AlarmType,
			Level:     v.Level,
			Threshold: v.Threshold,
			Value:     v.SValue,
			Sid:       v.Sid,
			Cid:       int(v.Cid),
			Cname:     v.Cname,
			UpdatedAt: util.MLTime(v.UpdatedAt),
		}
		ret = append(ret, oo)
	}
	o.Response(Success, "成功", ret)
}

// Alarm @Title 获取告警数据
// @Description 获取告警数据
// @Param body controllers.ReqAlarmData	true	"请求参数"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/alarm [post]
func (o *DataController) Alarm() {
	var obj ReqAlarmData
	if err := json.Unmarshal(o.Ctx.Input.RequestBody, &obj); err != nil {
		beego.Error(fmt.Sprintf("数据包解析错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("数据包解析错误:%s", err.Error()), nil)
		return
	}
	arr, err := models.GetAlarmByCodes(obj.Codes, obj.Flag)
	if err != nil {
		o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
		return
	}
	ret := make([]RespAlarm, 0, len(arr))
	for _, v := range arr {
		oo := RespAlarm{
			ID:        v.ID,
			DID:       v.DID,
			TStart:    util.MLTime(v.TStart),
			TEnd:      util.MLTime(v.TEnd),
			Content:   v.Content,
			AlarmType: v.AlarmType,
			Level:     v.Level,
			Threshold: v.Threshold,
			Value:     v.SValue,
			Sid:       v.Sid,
			Cid:       int(v.Cid),
			Cname:     v.Cname,
			UpdatedAt: util.MLTime(v.UpdatedAt),
		}
		ret = append(ret, oo)
	}
	o.Response(Success, "成功", ret)
}

// Energy @Title 获取能耗数据
// @Description 获取能耗数据
// @Param body controllers.ReqEnergy	true	"请求参数"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/energy [post]
func (o *DataController) Energy() {
	var obj ReqEnergy
	if err := json.Unmarshal(o.Ctx.Input.RequestBody, &obj); err != nil {
		beego.Error(fmt.Sprintf("数据包解析错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("数据包解析错误:%s", err.Error()), nil)
		return
	}

	ret := make(map[string][]RespEnergy)
	if obj.Flag == 1 {
		arr, err := models.GetDeviceEnergyDayData(obj.Codes, obj.Start, obj.End)
		if err != nil {
			o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
			return
		}
		for _, v := range arr {
			en := RespEnergy{
				Date:       v.Date.Format("2006-01-02"),
				Beginning:  v.Beginning,
				Ending:     v.Ending,
				Difference: v.Difference,
			}
			ret[v.ID] = append(ret[v.ID], en)
		}
	} else if obj.Flag == 2 {
		arr, err := models.GetDeviceEnergyMonthData(obj.Codes, obj.Start, obj.End)
		if err != nil {
			o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
			return
		}
		for _, v := range arr {
			en := RespEnergy{
				Date:       v.Date.Format("2006-01-02"),
				Beginning:  v.Beginning,
				Ending:     v.Ending,
				Difference: v.Difference,
			}
			ret[v.ID] = append(ret[v.ID], en)
		}
	} else {
		o.Response(Failure, fmt.Sprintf("flag为不支持的标识:flag=", obj.Flag), nil)
		return
	}
	o.Response(Success, "成功", ret)
}

// LightingRate @Title 获取亮灯率
// @Description 获取亮灯率
// @Param body controllers.ReqLightingRate	true	"请求参数"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/lightingrate [post]
func (o *DataController) LightingRate() {
	var obj ReqLightingRate
	if err := json.Unmarshal(o.Ctx.Input.RequestBody, &obj); err != nil {
		beego.Error(fmt.Sprintf("数据包解析错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("数据包解析错误:%s", err.Error()), nil)
		return
	}
	if err := obj.Validate(); err != nil {
		beego.Error(fmt.Sprintf("请求参数验证失败:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("请求参数验证失败:%s", err.Error()), nil)
		return
	}
	ret := RespDayLightingRateData{
		Tenant: obj.Tenant,
		Flag:   obj.Flag,
	}
	if obj.Flag == 0 {
		arr, err := models.GetDayLightingRateData(obj.Tenant, obj.Start, obj.End)
		if err == nil { //日
			Data := make([]DayLightingRateData, 0, len(arr))
			for _, v := range arr {
				lrd := DayLightingRateData{
					Date:   v.Date.Format("2006-01-02"),
					Total:  v.Total,
					Number: v.Number,
					Rate:   float64(v.Rate),
				}
				Data = append(Data, lrd)
			}
			o.Response(Success, "成功", RespDayLightingRateData{Tenant: obj.Tenant, Flag: obj.Flag, Data: Data})
		}
	} else if obj.Flag == 1 { //月
		ts, _ := time.Parse("2006-01-02", obj.Start)
		te, _ := time.Parse("2006-01-02", obj.End)
		arr, err := models.GetMonthLightingRateData(obj.Tenant, ts.Format("2006-01"), te.Format("2006-01"))
		if err == nil {
			Data := make([]MonthLightingRate, 0, len(arr))
			for _, v := range arr {
				Data = append(Data, MonthLightingRate{Month: v.Time, Rate: float64(v.Rate)})
			}
			o.Response(Success, "成功", RespMonthLightingRate{Tenant: obj.Tenant, Flag: obj.Flag, Data: Data})
		}
	} else if obj.Flag == 2 { //季度
		ts, _ := time.Parse("2006-01-02", obj.Start)
		te, _ := time.Parse("2006-01-02", obj.End)
		arr, err := models.GetQuarterLightingRateData(obj.Tenant, ts.Format("2006"), te.Format("2006"), obj.Quarter)
		if err == nil {
			Data := make([]QuarterLightingRate, 0, len(arr))
			for _, v := range arr {
				Data = append(Data, QuarterLightingRate{Quarter: v.Time, Rate: float64(v.Rate)})
			}
			o.Response(Success, "成功", RespQuarterLightingRate{Tenant: obj.Tenant, Flag: obj.Flag, Data: Data})
		}
	} else if obj.Flag == 3 { //年度
		ts, _ := time.Parse("2006-01-02", obj.Start)
		te, _ := time.Parse("2006-01-02", obj.End)
		arr, err := models.GetYearLightingRateData(obj.Tenant, ts.Format("2006"), te.Format("2006"))
		if err == nil {
			Data := make([]YearLightingRate, 0, len(arr))
			for _, v := range arr {
				Data = append(Data, YearLightingRate{Year: v.Time, Rate: float64(v.Rate)})
			}
			o.Response(Success, "成功", RespYearLightingRate{Tenant: obj.Tenant, Flag: obj.Flag, Data: Data})
		}
	}
	o.Response(Success, "成功", ret)
}

// Sos @Title 获取一键求助报警记录
// @Description 获取一键求助报警记录
// @Param body body controllers.ReqSosAlarm	true	"请求参数"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/sos [post]
func (o *DataController) Sos() {
	var obj ReqSosAlarm
	if err := json.Unmarshal(o.Ctx.Input.RequestBody, &obj); err != nil {
		beego.Error(fmt.Sprintf("数据包解析错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("数据包解析错误:%s", err.Error()), nil)
		return
	}
	arr, err := models.GetSosAlarm(obj.Codes, obj.Start, obj.End)
	if err != nil {
		o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
		return
	}
	ret := make([]RespSosAlarm, 0, len(arr))
	var duration uint = 0
	for _, v := range arr {
		if v.TEnd.IsZero() {
			duration = 0
		} else {
			duration = uint(v.TEnd.Sub(v.TStart).Seconds())
		}
		oo := RespSosAlarm{
			ID:        v.ID,
			DID:       v.DID,
			TStart:    util.MLTime(v.TStart),
			TEnd:      util.MLTime(v.TEnd),
			Duration:  duration,
			UpdatedAt: util.MLTime(v.UpdatedAt),
		}
		ret = append(ret, oo)
	}
	o.Response(Success, "成功", ret)
}

// SosSync @Title 同步一键求助报警记录
// @Description 同步一键求助报警记录
// @Param body controllers.ReqAlarmData	true	"请求参数"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/sos/sync [get]
func (o *DataController) SosSync() {
	id, _ := o.GetUint64("id")            //ID
	updatedat := o.GetString("updatedat") //更新时间
	arr, err := models.GetUpdateSosAlarm(id, updatedat)
	if err != nil {
		o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
		return
	}
	ret := make([]RespSosAlarm, 0, len(arr))
	var duration uint = 0
	for _, v := range arr {
		if v.TEnd.IsZero() {
			duration = 0
		} else {
			duration = uint(v.TEnd.Sub(v.TStart).Seconds())
		}
		oo := RespSosAlarm{
			ID:        v.ID,
			DID:       v.DID,
			TStart:    util.MLTime(v.TStart),
			TEnd:      util.MLTime(v.TEnd),
			Duration:  duration,
			UpdatedAt: util.MLTime(v.UpdatedAt),
		}
		ret = append(ret, oo)
	}
	o.Response(Success, "成功", ret)
}

// LampEvent @Title 获取开关灯记录
// @Description 获取开关灯记录
// @Param body body controllers.ReqLampEvent	true	"请求参数"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/lampevent [post]
func (o *DataController) LampEvent() {
	var obj ReqLampEvent
	if err := json.Unmarshal(o.Ctx.Input.RequestBody, &obj); err != nil {
		beego.Error(fmt.Sprintf("数据包解析错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("数据包解析错误:%s", err.Error()), nil)
		return
	}
	arr, err := models.GetLampEvents(obj.Codes, obj.Start, obj.End)
	if err != nil {
		o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
		return
	}
	ret := make([]RespLampEvent, 0, len(arr))
	var duration uint = 0
	for _, v := range arr {
		if v.TEnd.IsZero() {
			duration = 0
		} else {
			duration = uint(v.TEnd.Sub(v.TStart).Minutes())
		}
		oo := RespLampEvent{
			ID:         int64(v.ID),
			DID:        v.DID,
			TStart:     util.MLTime(v.TStart),
			TEnd:       util.MLTime(v.TEnd),
			Brightness: v.Brightness,
			Duration:   duration,
			UpdatedAt:  util.MLTime(v.UpdatedAt),
		}
		ret = append(ret, oo)
	}
	o.Response(Success, "成功", ret)
}

// LampEventSync @Title 同步开关灯记录
// @Description 同步开关灯记录
// @Param body body controllers.ReqAlarmData	true	"请求参数"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/lampevent/sync [get]
func (o *DataController) LampEventSync() {
	id, _ := o.GetUint64("id")            //ID
	updatedat := o.GetString("updatedat") //更新时间
	arr, err := models.GetUpdateLampEvents(id, updatedat)
	if err != nil {
		o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
		return
	}
	ret := make([]RespLampEvent, 0, len(arr))
	var duration uint = 0
	for _, v := range arr {
		if v.TEnd.IsZero() {
			duration = 0
		} else {
			duration = uint(v.TEnd.Sub(v.TStart).Seconds())
		}
		oo := RespLampEvent{
			ID:         int64(v.ID),
			DID:        v.DID,
			TStart:     util.MLTime(v.TStart),
			TEnd:       util.MLTime(v.TEnd),
			Brightness: v.Brightness,
			Duration:   duration,
			UpdatedAt:  util.MLTime(v.UpdatedAt),
		}
		ret = append(ret, oo)
	}
	o.Response(Success, "成功", ret)
}

// VehicleProvince @Title 获取车流量分省统计数据
// @Description 获取车流量分省统计数据
// @Param body controllers.ReqVehicleData	true	"请求参数"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/its/province [post]
func (o *DataController) VehicleProvince() {
	var obj ReqVehicleData
	if err := json.Unmarshal(o.Ctx.Input.RequestBody, &obj); err != nil {
		beego.Error(fmt.Sprintf("数据包解析错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("数据包解析错误:%s", err.Error()), nil)
		return
	}
	if err := obj.Validate(); err != nil {
		beego.Error(fmt.Sprintf("请求参数校验错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("请求参数校验错误:%s", err.Error()), nil)
		return
	}
	arr, err := models.GetVehicleProvince(obj.Codes, obj.Start, obj.End, obj.Flag)
	if err != nil {
		o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
		return
	}
	o.Response(Success, "成功", arr)
}

// VehicleCity @Title 获取车流量分城市统计数据
// @Description 获取车流量分城市统计数据
// @Param body controllers.ReqVehicleData	true	"请求参数"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/its/provincecity [post]
func (o *DataController) VehicleCity() {
	var obj ReqVehicleData
	if err := json.Unmarshal(o.Ctx.Input.RequestBody, &obj); err != nil {
		beego.Error(fmt.Sprintf("数据包解析错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("数据包解析错误:%s", err.Error()), nil)
		return
	}
	if err := obj.Validate(); err != nil {
		beego.Error(fmt.Sprintf("请求参数校验错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("请求参数校验错误:%s", err.Error()), nil)
		return
	}
	arr, err := models.GetVehicleProvinceCity(obj.Codes, obj.Start, obj.End, obj.Flag)
	if err != nil {
		o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
		return
	}
	o.Response(Success, "成功", arr)
}

// VehicleType @Title 获取车流量分车型统计数据
// @Description 获取车流量分车型统计数据
// @Param body controllers.ReqVehicleData	true	"请求参数"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/its/vehicletype [post]
func (o *DataController) VehicleType() {
	var obj ReqVehicleData
	if err := json.Unmarshal(o.Ctx.Input.RequestBody, &obj); err != nil {
		beego.Error(fmt.Sprintf("数据包解析错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("数据包解析错误:%s", err.Error()), nil)
		return
	}
	if err := obj.Validate(); err != nil {
		beego.Error(fmt.Sprintf("请求参数校验错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("请求参数校验错误:%s", err.Error()), nil)
		return
	}
	arr, err := models.GetVehicleType(obj.Codes, obj.Start, obj.End, obj.Flag)
	if err != nil {
		o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
		return
	}
	o.Response(Success, "成功", arr)
}

// VehicleTypeEx @Title 获取车流量分车型统计数据
// @Description 获取车流量分车型统计数据
// @Param body controllers.ReqVehicleData	true	"请求参数"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/its/vehicletypeex [post]
func (o *DataController) VehicleTypeEx() {
	var obj ReqVehicleData
	if err := json.Unmarshal(o.Ctx.Input.RequestBody, &obj); err != nil {
		beego.Error(fmt.Sprintf("数据包解析错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("数据包解析错误:%s", err.Error()), nil)
		return
	}
	if err := obj.Validate(); err != nil {
		beego.Error(fmt.Sprintf("请求参数校验错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("请求参数校验错误:%s", err.Error()), nil)
		return
	}
	arr, err := models.GetVehicleTypeEx(obj.Codes, obj.Start, obj.End, obj.Types, obj.Flag)
	if err != nil {
		o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
		return
	}
	o.Response(Success, "成功", arr)
}

// VehicleTotal @Title 获取车流量统计数据
// @Description 获取车流量统计数据
// @Param body controllers.ReqVehicleData	true	"请求参数"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/its/vehicletotal [post]
func (o *DataController) VehicleTotal() {
	var obj ReqVehicleData
	if err := json.Unmarshal(o.Ctx.Input.RequestBody, &obj); err != nil {
		beego.Error(fmt.Sprintf("数据包解析错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("数据包解析错误:%s", err.Error()), nil)
		return
	}
	if err := obj.Validate(); err != nil {
		beego.Error(fmt.Sprintf("请求参数校验错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("请求参数校验错误:%s", err.Error()), nil)
		return
	}
	arr, err := models.GetVehicleStreamsTag(obj.Codes, obj.Start, obj.End, obj.Flag)
	if err != nil {
		o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
		return
	}
	o.Response(Success, "成功", arr)
}

// VehicleHourTotal @Title 获取车流量按小时统计数据
// @Description 获取车流量按小时统计数据
// @Param  body controllers.ReqVehicleData	true	"请求参数"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/its/vehiclehourtotal [post]
func (o *DataController) VehicleHourTotal() {
	var obj ReqVehicleData
	if err := json.Unmarshal(o.Ctx.Input.RequestBody, &obj); err != nil {
		beego.Error(fmt.Sprintf("数据包解析错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("数据包解析错误:%s", err.Error()), nil)
		return
	}
	if err := obj.Validate(); err != nil {
		beego.Error(fmt.Sprintf("请求参数校验错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("请求参数校验错误:%s", err.Error()), nil)
		return
	}
	arr, err := models.GetVehicleHourTotalTag(obj.Codes, obj.Start, obj.End)
	if err != nil {
		o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
		return
	}
	o.Response(Success, "成功", arr)
}

// VehicleSpeedTotal @Title 获取速度区间统计数据
// @Description 获取速度区间统计数据
// @Param body controllers.ReqVehicleData	true	"请求参数"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/its/vehiclespeedtotal [post]
func (o *DataController) VehicleSpeedTotal() {
	var obj ReqVehicleData
	if err := json.Unmarshal(o.Ctx.Input.RequestBody, &obj); err != nil {
		beego.Error(fmt.Sprintf("数据包解析错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("数据包解析错误:%s", err.Error()), nil)
		return
	}
	if err := obj.Validate(); err != nil {
		beego.Error(fmt.Sprintf("请求参数校验错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("请求参数校验错误:%s", err.Error()), nil)
		return
	}
	arr, err := models.GetVehicleSpeedRange(obj.Codes, obj.Start, obj.End, obj.Flag)
	if err != nil {
		o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
		return
	}
	o.Response(Success, "成功", arr)
}

// VehicleOverSpeedTotal @Title 获取车辆超速统计数据
// @Description 获取车辆超速统计数据
// @Param  body controllers.ReqVehicleData	true	"请求参数"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/its/vehicleoverspeedtotal [post]
func (o *DataController) VehicleOverSpeedTotal() {
	var obj ReqVehicleData
	if err := json.Unmarshal(o.Ctx.Input.RequestBody, &obj); err != nil {
		beego.Error(fmt.Sprintf("数据包解析错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("数据包解析错误:%s", err.Error()), nil)
		return
	}
	if err := obj.Validate(); err != nil {
		beego.Error(fmt.Sprintf("请求参数校验错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("请求参数校验错误:%s", err.Error()), nil)
		return
	}
	arr, err := models.GetVehicleOverSpeed(obj.Codes, obj.Start, obj.End, obj.Flag)
	if err != nil {
		o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
		return
	}
	o.Response(Success, "成功", arr)
}

// VehiclePlate @Title 获取车牌数据
// @Description 获取车牌数据
// @Param body controllers.ReqVehicleData	true	"请求参数"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/its/vehicleplate [post]
func (o *DataController) VehiclePlate() {
	var obj ReqVehicleData
	if err := json.Unmarshal(o.Ctx.Input.RequestBody, &obj); err != nil {
		beego.Error(fmt.Sprintf("数据包解析错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("数据包解析错误:%s", err.Error()), nil)
		return
	}
	if err := obj.Validate(); err != nil {
		beego.Error(fmt.Sprintf("请求参数校验错误:%s", err.Error()))
		o.Response(Failure, fmt.Sprintf("请求参数校验错误:%s", err.Error()), nil)
		return
	}
	arr, err := models.GetVehiclePlate(obj.Codes, obj.Start, obj.End, obj.Types)
	if err != nil {
		o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
		return
	}
	o.Response(Success, "成功", arr)
}

// OverSpeedPlateSync @Title 超速车牌数据同步
// @Description 超速车牌数据同步
// @Param body controllers.ReqAlarmData	true	"请求参数"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/its/overspeed/sync [get]
func (o *DataController) OverSpeedPlateSync() {
	id, _ := o.GetInt64("id", 0)  //ID
	start := o.GetString("start") //开始时间
	end := o.GetString("end")     //结束时间
	arr, err := models.GetOverSpeedPlate(id, start, end)
	if err != nil {
		o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
		return
	}
	o.Response(Success, "成功", arr)
}

// NBIOTData @Title NB-IOT井盖监测数据订阅
// @Description NB-IOT井盖监测数据订阅
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/nbiotdata [get,post]
func (o *DataController) NBIOTData() {
	beego.Info(o.Ctx.Request.RequestURI)
	beego.Info(string(o.Ctx.Input.RequestBody))
}

// RadarDataList @Title 获取雷达详细数据
// @Description 获取雷达详细数据
// @Param body controllers.ReqRadarDataList "请求参数"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/radar/list [post]
func (o *DataController) RadarDataList() {
	var obj ReqRadarDataList
	if err := json.Unmarshal(o.Ctx.Input.RequestBody, &obj); err != nil {
		o.Response(Failure, fmt.Sprintf("数据包解析错误:%s", err.Error()), nil)
		return
	}
	ret := make(map[string][]RadarData)

	arr, err := models.GetRadarDataList(obj.Codes, obj.Start, obj.End, obj.Model)
	if err != nil {
		o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
		return
	}
	for _, v := range arr {
		d := RadarData{
			Time:  util.MLTime(v.Time),
			Model: v.Type,
			Speed: v.Speed,
			Dist:  v.Dist,
		}
		if m, ok := ret[v.DID]; !ok {
			m = append(m, d)
			ret[v.DID] = m
		} else {
			m = append(m, d)
		}
	}

	o.Response(Success, "成功", ret)
}

// RadarDataSummary @Title 获取雷达统计数据
// @Description 获取雷达统计数据
// @Param body controllers.ReqRadarSummaryData "请求参数"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/radar/summary [post]
func (o *DataController) RadarDataSummary() {
	var obj ReqRadarSummaryData
	if err := json.Unmarshal(o.Ctx.Input.RequestBody, &obj); err != nil {
		o.Response(Failure, fmt.Sprintf("数据包解析错误:%s", err.Error()), nil)
		return
	}
	ret := make(map[string][]RadarSummaryData)
	if obj.Type == 1 {
		arr, err := models.GetRadarSummaryHourData(obj.Codes, obj.Start, obj.End, obj.Model)
		if err != nil {
			o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
			return
		}
		for _, v := range arr {
			d := RadarSummaryData{
				Time:            util.MLTime(v.Time),
				Model:           v.Type,
				Speed20Number:   v.Speed20Number,
				Speed40Number:   v.Speed40Number,
				Speed60Number:   v.Speed60Number,
				Speed80Number:   v.Speed80Number,
				Speed100Number:  v.Speed100Number,
				Speed120Number:  v.Speed120Number,
				OverSpeedNumber: v.OverSpeedNumber,
				SpeedMaxNumber:  v.SpeedMaxNumber,
				Total:           v.Total,
			}
			if m, ok := ret[v.DID]; !ok {
				m = append(m, d)
				ret[v.DID] = m
			} else {
				m = append(m, d)
			}
		}
		// 默认为2 查询日统计
	} else if obj.Type == 2 || obj.Type == 0 {
		arr, err := models.GetRadarSummaryDayData(obj.Codes, obj.Start, obj.End, obj.Model)
		if err != nil {
			o.Response(Failure, fmt.Sprintf("数据查询错误:%s", err.Error()), nil)
			return
		}
		for _, v := range arr {
			d := RadarSummaryData{
				Time:            util.MLTime(v.Date),
				Model:           v.Type,
				Speed20Number:   v.Speed20Number,
				Speed40Number:   v.Speed40Number,
				Speed60Number:   v.Speed60Number,
				Speed80Number:   v.Speed80Number,
				Speed100Number:  v.Speed100Number,
				Speed120Number:  v.Speed120Number,
				OverSpeedNumber: v.OverSpeedNumber,
				SpeedMaxNumber:  v.SpeedMaxNumber,
				Total:           v.Total,
			}
			if m, ok := ret[v.DID]; !ok {
				m = append(m, d)
				ret[v.DID] = m
			} else {
				m = append(m, d)
			}
		}
	}
	o.Response(Success, "成功", ret)
}
