package main

import (
	"encoding/json"
	"github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"
	_ "github.com/mattn/go-sqlite3"
	"io/ioutil"
	"log"
	"math"
	"net/http"
	"strconv"
	"strings"
	"sync"
	"time"
	"bytes"
)

var router = gin.Default()

// GW网关api路由
func gw_router() {
	router.Use(cors.Default())
	v1 := router.Group("/api/v1")
	{
		v1.GET("/weather", gw_weather_api)
		v1.POST("/renliu", get_renliu_api)
		v1.POST("/feedback", get_pj_api)
		v1.GET("/totalWater", sb_api)
		v1.GET("/totalElectricity", db_api)
		v1.GET("/environmentDate", kq_api)
		v1.GET("/traffic", renliu_api)
		v1.GET("/stink", aq_api)
		v1.GET("/satisfaction", pj_api)
		v1.GET("/seat/:id", seat_api)
		v1.POST("/push", push)
		v1.POST("/pushv2", pushv2)

		v1.GET("/getConf")

	}



	router.Run(":10086")
}

type DparkConf struct {
	ExtensionInTime  int `json:"in"`
	ExtensionOutTime int `json:"out"`
	ExtensionInTime2  int `json:"in2"`
	ExtensionOutTime2 int `json:"out2"`
}

var dparkConf DparkConf

//获取数据防抖配置时间
func getConf() {
	resp, err := http.Get("https://smartoilets.cn/socketServer/dpark/getConf")
	if err != nil {
		// handle error
		log.Println("getConf.get.err", err)
		return
	}

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		// handle error
		log.Println("getConf.readData.err", err)
		return
	}

	if err := json.Unmarshal([]byte(body), &dparkConf); err == nil {
		log.Println("yunhorndebug.getConf.success:", dparkConf)
	}

	if err!=nil{
		return
	}

	if dparkConf.ExtensionInTime == 0 && dparkConf.ExtensionOutTime == 0 {
		return
	}

	if dparkConf.ExtensionInTime < 0 {
		dparkConf.ExtensionInTime = 0
	}

	if dparkConf.ExtensionOutTime < 0 {
		dparkConf.ExtensionOutTime = 0
	}

	extensionInTime = dparkConf.ExtensionInTime
	extensionOutTime = dparkConf.ExtensionOutTime

	// check(err)

}

//距离有效判断
var reactTof = 1650

//数据防抖 进入时间
var extensionInTime = 6

//数据防抖 离开时间
var extensionOutTime = 10

var extensionInTime2 = 0

var extensionOutTime2 = 0

var oldData1 = ""

var oldData2 = ""

var oldData3 = ""

var dataMap sync.Map

//接收传感器push来的数据,解析并上传到云端
func push(c *gin.Context) {

		data := c.PostForm("d")

 		go dealData(data)

		log.Println("data:", data)
		c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": data})

}

func dealData(data string) string{

	nowtime := time.Now()

	log.Println("yunhorndeug.push.data|", data)

//	go pushCODE1007(data)

	alldata := strings.Split(data, "#")

	if len(alldata) != 2 {
		// c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "ok"})
		return ""
	} else {

		valuedata := strings.Split(alldata[1], "*")

		if len(valuedata) < 1 {
			// c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "ok"})
			return ""
		}

		dtype, error := strconv.Atoi(valuedata[0])
		if error != nil {
			// c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "errtype"})
			return ""
		}

		var nowTmpData = "1#0"

		if dtype == 1 {
			if len(valuedata) != 3 {
				// c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "valuedata not 3"})
				return ""
			}
			addr, error := strconv.Atoi(alldata[0])
			if error != nil {
				// c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "erraddr"})
				return ""
			}
			cs2001, error := strconv.Atoi(valuedata[1])
			if error != nil {
				// c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "errcs2001"})
				return ""
			}

			tof, error := strconv.Atoi(valuedata[2])
			if error != nil {
				// c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "errtof"})
				return ""
			}

			if tof ==0{
				log.Println("tof is zero")
				return ""
			}

			if addr == 1 {

				if cs2001 == 1 || tof < 1650 {
					nowTmpData = "1#1"
				}

				if oldData1 != nowTmpData {
					dataMap.Store(addr, nowtime)
					if oldData1 == "" {
						//为空 直接改变状态
						maledemoDevice.DATA["data1"] = 0
						if nowTmpData == "1#1" {
							maledemoDevice.DATA["data1"] = 1
						}
						changeData(2, maledemoDevice)
					}
					//存储状态
					oldData1 = nowTmpData

				} else {
					oldDevDataTime, ok := dataMap.Load(addr)
					if !ok {
						log.Println("load time err", ok)
					}

					if ok {
						if oldDevDataTime != nil {
							//log.Println("t2.Sub(t1)", nowtime.Sub(oldDevDataTime.(time.Time)))

							var duration = nowtime.Sub(oldDevDataTime.(time.Time)).Seconds()
							var durationAsInt64 = int(duration)

							log.Printf("yunhorndebug.origin.%s|%s|%d|%d|%d|%d|%d", oldData1, nowTmpData, addr, dtype, cs2001, tof, durationAsInt64)

							if nowTmpData == "1#0" {
								if durationAsInt64 < extensionOutTime {
									// c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "not enough time"})
									return ""
								}
							} else {
								if durationAsInt64 < extensionInTime {
									// c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "not enough time"})
									return ""
								}
							}
							maledemoDevice.DATA["data1"] = 0
							if nowTmpData == "1#1" {
								maledemoDevice.DATA["data1"] = 1
							}

							changeData(2, maledemoDevice)
							dataMap.Delete(addr)
						}
					}
				}

			} else if addr == 2 {
				if cs2001 == 1 || tof < 1650 {
					nowTmpData = "1#1"
				}

				if oldData2 != nowTmpData {
					dataMap.Store(addr, nowtime)
					if oldData2 == "" {
						//为空 直接改变状态
						maledemoDevice.DATA["data2"] = 0
						if nowTmpData == "1#1" {
							maledemoDevice.DATA["data2"] = 1
						}
						changeData(2, maledemoDevice)
					}
					//存储状态
					oldData2 = nowTmpData

				} else {
					oldDevDataTime, ok := dataMap.Load(addr)
					if !ok {
						log.Println("load time err", ok)
					}

					if ok {
						if oldDevDataTime != nil {
							//log.Println("t2.Sub(t1)", nowtime.Sub(oldDevDataTime.(time.Time)))

							var duration = nowtime.Sub(oldDevDataTime.(time.Time)).Seconds()
							var durationAsInt64 = int(duration)

							log.Printf("yunhorndebug.origin.%s|%s|%d|%d|%d|%d|%d", oldData2, nowTmpData, addr, dtype, cs2001, tof, durationAsInt64)

							if nowTmpData == "1#0" {
								if durationAsInt64 < extensionOutTime {
									// c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "not enough time"})
									return ""
								}
							} else {
								if durationAsInt64 < extensionInTime {
									// c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "not enough time"})
									return ""
								}
							}
							maledemoDevice.DATA["data2"] = 0
							if nowTmpData == "1#1" {
								maledemoDevice.DATA["data2"] = 1
							}

							changeData(2, maledemoDevice)
							dataMap.Delete(addr)
						}
					}
				}
			}

		} else if dtype == 2 {
			//吸顶传感器  没有距离数据
			if len(valuedata) != 2 {
				// c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "valuedata not 2,type2"})
				return ""
			}
			addr, error := strconv.Atoi(alldata[0])
			if error != nil {
				// c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "erraddr"})
				return ""
			}
			cs2001, error := strconv.Atoi(valuedata[1])
			if error != nil {
				// c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "errcs2001"})
				return ""
			}

			if cs2001 == 1 {
				nowTmpData = "1#1"
			}

			if oldData3 != nowTmpData {
				dataMap.Store(addr, nowtime)
				if oldData3 == "" {
					//为空 直接改变状态
					femaledemoDevice.DATA["data1"] = 0
					if nowTmpData == "1#1" {
						femaledemoDevice.DATA["data1"] = 1
					}
					changeData(2, maledemoDevice)
				}
				//存储状态
				oldData3 = nowTmpData

			} else {
				oldDevDataTime, ok := dataMap.Load(addr)
				if !ok {
					log.Println("load time err", ok)
				}

				if ok {
					if oldDevDataTime != nil {
						//log.Println("t2.Sub(t1)", nowtime.Sub(oldDevDataTime.(time.Time)))

						var duration = nowtime.Sub(oldDevDataTime.(time.Time)).Seconds()
						var durationAsInt64 = int(duration)

						var tof = 0

						log.Printf("yunhorndebug.origin.%s|%s|%d|%d|%d|%d|%d", oldData3, nowTmpData, addr, dtype, cs2001, tof, durationAsInt64)

						if nowTmpData == "1#0" {
							if durationAsInt64 < extensionOutTime {
								// c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "not enough time"})
								return ""
							}
						} else {
							if durationAsInt64 < extensionInTime {
								// c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "not enough time"})
								return ""
							}
						}

						femaledemoDevice.DATA["data1"] = 0
						if nowTmpData == "1#1" {
							femaledemoDevice.DATA["data1"] = 1
						}
						changeData(3, femaledemoDevice)
						dataMap.Delete(addr)
					}
				}
			}
		}
	}
	return ""
}


func pushv2(c *gin.Context){
	data := c.PostForm("d")

	// go dealDatav2(data)

	log.Println("data:", data)
	c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "code": 1})

}

func dealDatav3(data []byte) string{

	nowtime := time.Now()

	log.Println("yunhorndeug.push.data|", data)

	strs := data

  buffer := new(bytes.Buffer)
	for _, b := range data[:4] {
		s := strconv.FormatInt(int64(b&0xff), 16)
		if len(s) == 1 {
				buffer.WriteString("0")
		}
		buffer.WriteString(s)
	}

	adr := buffer.String()

	var readyData bytes.Buffer

	datatype := data[5]

	cs2001 := data[6]

	var R_data P1004_6
	R_data.CODE = 1008
	R_data.ID = adr
	//尿布台
	R_data.VERSION = "yunhorn_2_v1"
	R_data.ONLINE = true
	R_data.DATA = make(map[string]interface{})
	R_data.DATA["cs2001"]=cs2001


	datatypeStr := strconv.FormatInt(int64(data[5]&0xff), 16)

	cs2001Str := strconv.FormatInt(int64(data[6]&0xff), 16)

	//地址
	readyData.WriteString(buffer.String())
	readyData.WriteString("#")
	//类型
	readyData.WriteString(datatypeStr)
	readyData.WriteString("*")
	//红外人体感应
	readyData.WriteString(cs2001Str)

  newdtype := strs[5]

	tmp := []byte{0, 0}
	tof := tmp[0]

	if newdtype==1{
		tof = data[7]
		R_data.VERSION = "yunhorn_1_v1"
		R_data.DATA["tof"]=tof
		tofTmp := strconv.FormatInt(int64(data[7]&0xff), 10)
		readyData.WriteString("*")
		readyData.WriteString(tofTmp)
	}

	data_bufTmp, _ := json.Marshal(R_data)
	data_buf := string(data_bufTmp)
	go post_to_server(data_buf)

	// log.Println("readyData:",readyData.String())

//	go pushCODE1007(data)

	//默认当前无人占用
	current := 0

	if datatype == 1 {
		//尿布台类型
		if cs2001==1 || tof<130{
			//有人占用
			current = 1
		}
	}else if datatype==2{
		//吸顶类型
		if cs2001 ==1 {
			//有人占用
			current = 1
		}
	}

	// log.Println("loraNodeMap:",loraNodeMap)
	loraNode, ok := loraNodeMap.Load(adr)
	if !ok {
		log.Println("load loraNode success ", ok)
		return ""
	}
	// log.Println("load loraNode:",loraNode)

	log.Println("yunhorndeug.push.data.cuurent_data,current",loraNode.(LoraNode).CURRENT_DATA,current)
	if loraNode.(LoraNode).CURRENT_DATA != current{
			//不相同,直接改变状态,更新时间

			// loraNode.(LoraNode).CURRENT_DATA = current
			// loraNode.(LoraNode).TIME = time.Now()
			// loraNode.(LoraNode).CHECK_TIME = true

			newLoraNode := LoraNode{}
			newLoraNode.CURRENT_DATA = current
			newLoraNode.TIME = time.Now()
			newLoraNode.CHECK_TIME=true

			newLoraNode.LOCATION_TYPE = loraNode.(LoraNode).LOCATION_TYPE
			newLoraNode.LOCATION_CODE = loraNode.(LoraNode).LOCATION_CODE
			newLoraNode.LOCATION_DATA = loraNode.(LoraNode).LOCATION_DATA
			newLoraNode.DEVICE = loraNode.(LoraNode).DEVICE

			loraNodeMap.Store(adr,newLoraNode)

			//初次启动
			if loraNode.(LoraNode).CURRENT_DATA == -1{
					changeDataV2(newLoraNode)
			}


	}else{
		// 非首次
		if loraNode.(LoraNode).CHECK_TIME {

			var duration = nowtime.Sub(loraNode.(LoraNode).TIME).Seconds()
			var durationAsInt64 = int(duration)

			log.Println("yunhorndeug.push.data.durationAsInt64:",durationAsInt64)
			if current == 0 {
				//类型2 吸顶
					if datatype==2{
						if durationAsInt64 < extensionOutTime2 {
							return ""
						}
					}else{
						if durationAsInt64 < extensionOutTime {
							return ""
						}
					}

			}else{
				//类型2 吸顶
				if datatype==2{
					if durationAsInt64 < extensionInTime2 {
						return ""
					}
				}else{
					if durationAsInt64 < extensionInTime {
						return ""
					}
				}

			}

			//改变状态
			// loraNode.(LoraNode).CHECK_TIME = false

			newLoraNode := LoraNode{}
			newLoraNode.CURRENT_DATA = current
			newLoraNode.TIME = loraNode.(LoraNode).TIME
			newLoraNode.CHECK_TIME= false

			newLoraNode.LOCATION_TYPE = loraNode.(LoraNode).LOCATION_TYPE
			newLoraNode.LOCATION_CODE = loraNode.(LoraNode).LOCATION_CODE
			newLoraNode.LOCATION_DATA = loraNode.(LoraNode).LOCATION_DATA
			newLoraNode.DEVICE = loraNode.(LoraNode).DEVICE
			loraNodeMap.Store(adr,newLoraNode)

			changeDataV2(newLoraNode)
		}else{
			// loraNode.(LoraNode).CHECK_TIME = true
			newLoraNode := LoraNode{}
			newLoraNode.CURRENT_DATA = loraNode.(LoraNode).CURRENT_DATA
			newLoraNode.TIME = time.Now()
			newLoraNode.CHECK_TIME= true

			newLoraNode.LOCATION_TYPE = loraNode.(LoraNode).LOCATION_TYPE
			newLoraNode.LOCATION_CODE = loraNode.(LoraNode).LOCATION_CODE
			newLoraNode.LOCATION_DATA = loraNode.(LoraNode).LOCATION_DATA
			newLoraNode.DEVICE = loraNode.(LoraNode).DEVICE

			loraNodeMap.Store(adr,newLoraNode)
		}
	}

	// log.Println("current:",current)
	// log.Println("loraNode:",loraNode)
	// log.Println("loraNode.time.is nil",(loraNode==nil))

	return ""
}

//发送code1007数据到云端
func pushCODE1007(data string) {

	//resp, err := http.PostForm("https://smartoilets.cn/socketServer/static/push",
	//	url.Values{"d": {data}})

	resp, err := http.Post("https://smartoilets.cn/socketServer/statis/push",
		"application/x-www-form-urlencoded",
		strings.NewReader("d="+data))
	if err != nil {
		log.Print("yunhorndebug.pushCODE1007.err", err)
	}

	defer resp.Body.Close()
}

func changeData(num int, device Device) {
	log.Println("device:", device)
	DEVICEDATAS.DATA[demoDevice.VERSION+"_"+strconv.Itoa(num)] = device
}

func changeDataV2(loraNode LoraNode){
	// log.Println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
	// log.Println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@00000:",loraNode)
	// log.Println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@11111:",DEVICEDATAS.DATA[loraNode.DEVICE])
	DEVICEDATAS.RLock()
	DEVICEDATAS.DATA[loraNode.DEVICE].DATA[loraNode.LOCATION_DATA] = loraNode.CURRENT_DATA
	DEVICEDATAS.RUnlock()
	log.Println("yunhorndeug.push.data.@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@22222:",DEVICEDATAS.DATA[loraNode.DEVICE])
	// log.Println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
}

type EventNotificationAlert struct {
	IPADDRESS        string         `xml:"ipAddress" json:"ipAddress"`
	PROTOCOLTYPE     string         `xml:"protocolType" json:"protocolType"`
	MACADDRESS       string         `xml:"macAddress" json:"macAddress"`
	CHANNELID        uint16         `xml:"channelID" json:"channelID"`
	DATETIME         string         `xml:"dateTime" json:"dateTime"`
	ACTIVEPOSTCOUNT  uint16         `xml:"activePostCount" json:"activePostCount"`
	EVENTTYPE        string         `xml:"eventType" json:"eventType"`
	EVENTSTATE       string         `xml:"eventState" json:"eventState"`
	EVENTDESCRIPTION string         `xml:"eventDescription" json:"eventDescription"`
	CHANNELNAME      string         `xml:"channelName" json:"channelName"`
	PEOPLECOUNTING   PeopleCounting `xml:"peopleCounting" json:"peopleCounting"`
}

type PeopleCounting struct {
	STATISTICALMETHODS string    `xml:"statisticalMethods" json:"statisticalMethods"`
	TIMERANGE          Timerange `xml:"TimeRange" json:"TimeRange"`
	ENTER              uint16    `xml:"enter" json:"enter"`
	EXIT               uint16    `xml:"exit" json:"exit"`
	PASS               uint16    `xml:"pass" json:"pass"`
}

type Timerange struct {
	STARTTIME string `xml:"startTime" json:"startTime"`
	ENDTIME   string `xml:"endTime" json:"endTime"`
}

type FeedBack struct {
	FEEDBACK string `json:"feedback"`
	ID       string `json:"id"`
}

var rl_data EventNotificationAlert

// 提交人流量api
func get_renliu_api(c *gin.Context) {
	err := c.Bind(&rl_data)
	if conf.DEBUG {
		log.Println(rl_data)
	}
	check(err)
	send_data(1004)
	c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": rl_data})
}

var pj_data FeedBack

// 提交评价api
func get_pj_api(c *gin.Context) {
	err = c.Bind(&pj_data)
	check(err)
	send_data(1006)
	c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": pj_data})
}

// 获取水表api
func sb_api(c *gin.Context) {
	DEVICEDATAS.RLock()
	var data = make(map[string]uint16)
	for _, i := range conf.DEVICES_LIST {
		if i[2] == "yunhorn_sb_c_v1" {
			if DEVICEDATAS.DATA[i[2]+"_"+i[3]].DATA["totalWater"] != nil {
				data["totalWater"] = data["totalWater"] + DEVICEDATAS.DATA[i[2]+"_"+i[3]].DATA["totalWater"].(uint16)
			}
		}
	}
	DEVICEDATAS.RUnlock()
	c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": data})
}

// 获取电表api
func db_api(c *gin.Context) {
	DEVICEDATAS.RLock()
	var data = make(map[string]float32)
	for _, i := range conf.DEVICES_LIST {
		if i[2] == "yunhorn_db_c_v1" {
			if DEVICEDATAS.DATA[i[2]+"_"+i[3]].DATA["totalElectric"] != nil {
				data["totalElectric"] = data["totalElectric"] + DEVICEDATAS.DATA[i[2]+"_"+i[3]].DATA["totalElectric"].(float32)
			}
		}
	}
	DEVICEDATAS.RUnlock()
	c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": data})
}

// 获取空气数据api
func kq_api(c *gin.Context) {
	DEVICEDATAS.RLock()
	var sum float32
	var toinitdata float32 = 0.0
	var data = make(map[string]interface{})
	for _, i := range conf.DEVICES_LIST {
		if i[2] == "yunhorn_kq_c_v1" {
			sum++
			for k, j := range DEVICEDATAS.DATA[i[2]+"_"+i[3]].DATA {
				if j != nil {
					data[k] = toinitdata
					data[k] = (data[k].(float32) + j.(float32)) / sum
				}
			}
		}
	}
	DEVICEDATAS.RUnlock()
	c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": data})
}

// 获取氨气数据api
func aq_api(c *gin.Context) {
	DEVICEDATAS.RLock()
	var sum uint16
	var toinitdata uint16 = 0
	var data_buf = make(map[string]interface{})
	var data = make(map[string]interface{})
	for _, i := range conf.DEVICES_LIST {
		if i[2] == "yunhorn_aq_c_v1" {
			sum++
			if DEVICEDATAS.DATA[i[2]+"_"+i[3]].DATA["氨气"] != nil {
				data_buf["氨气"] = toinitdata
				data_buf["氨气"] = (data_buf["氨气"].(uint16) + DEVICEDATAS.DATA["yunhorn_aq_c_v1_"+i[3]].DATA["氨气"].(uint16)) / sum
			}
		}
	}
	if data_buf["氨气"] == nil {
		data["stink"] = "无味"
	} else {
		if data_buf["氨气"].(uint16) <= 1 {
			data["stink"] = "无味"
		} else if data_buf["氨气"].(uint16) > 1 && data_buf["氨气"].(uint16) <= 10 {
			data["stink"] = "有味"
		} else if data_buf["氨气"].(uint16) > 10 && data_buf["氨气"].(uint16) <= 40 {
			data["stink"] = "恶臭"
		} else if data_buf["氨气"].(uint16) > 40 && data_buf["氨气"].(uint16) <= 100 {
			data["stink"] = "超级恶臭"
		}
	}
	DEVICEDATAS.RUnlock()
	c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": data})
}

// 获取人流量api
func renliu_api(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": traffic_data})
}

// 获取评价api
func pj_api(c *gin.Context) {
	var data float64
	data = good / (good + bad)
	satisfaction_data.SATISFACTION = Round(data, 2)
	c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": satisfaction_data})
}

// 精确到小数点后n位
func Round(f float64, n int) float64 {
	n10 := math.Pow10(n)
	return math.Trunc((f+0.5/n10)*n10) / n10
}

type Seat_data struct {
	POSITIONLIST   []interface{} `json:"positionList"`
	HASPERSONLIST  []interface{} `json:"hasPersonList"`
	EMPTYPOSITION  uint16        `json:"emptyPosition"`
	OCCUPYPOSITION uint16        `json:"occupyPosition"`
}

// 厕位占用api
func seat_api(c *gin.Context) {
	DEVICEDATAS.RLock()
	type_id := c.Param("id")
	var data Seat_data
	var conf_data [][]interface{}
	//conf.GATEWAY_INFO.CONFIG 采集器配置信息
	for _, i := range conf.GATEWAY_INFO.CONFIG {

		//if i.ID == "deb03e28-ddcb-4e5d-aa31-d870a1f0f09b" {
		//	log.Println("begin debug")
		//}

		arr := get_seat_device_data(i.ID)
		//获取到设备版本
		version, num := arr[0], arr[1]

		//if i.ID == "deb03e28-ddcb-4e5d-aa31-d870a1f0f09b" {
		//	log.Println("conf.data:", i.DATA)
		//	log.Println("devicedatas.data:", DEVICEDATAS.DATA)
		//}

		for k, j := range i.DATA {
			if DEVICEDATAS.DATA[version+"_"+num].DATA != nil {
				//if i.ID == "deb03e28-ddcb-4e5d-aa31-d870a1f0f09b" {
				//	log.Println("data:", DEVICEDATAS.DATA[version+"_"+num].DATA)
				//}

				// log.Println("============================devicedatas.data:", DEVICEDATAS.DATA[version+"_"+num].DATA)
				if DEVICEDATAS.DATA[version+"_"+num].DATA["data"+strconv.Itoa(k+1)] != nil {
					// log.Println("==========================do.data:", DEVICEDATAS.DATA[version+"_"+num].DATA["data"+strconv.Itoa(k+1)])
					j = append(j, DEVICEDATAS.DATA[version+"_"+num].DATA["data"+strconv.Itoa(k+1)])
				}
			}
			conf_data = append(conf_data, j)
		}
	}

	log.Println("end conf.data:", conf_data)

	switch type_id {
	case "1":
		data = scan_seat_from_confdata("男厕位", conf_data)
	case "2":
		data = scan_seat_from_confdata("男便池", conf_data)
	case "3":
		data = scan_seat_from_confdata("女厕位", conf_data)
	case "4":
		data = scan_seat_from_confdata("母婴", conf_data)
	case "5":
		data = scan_seat_from_confdata("残卫", conf_data)
	}
	DEVICEDATAS.RUnlock()
	c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": data})
}

// 拼凑位置信息的数据
func get_seat_device_data(id string) []string {
	//log.Println("begin get_seat_device_data.id:", id)
	var data = make([]string, 2)
	//配置表中devices_list
	//例如["4E5D52DD-EB81-43C0-A2B6-04E432412EBA", "loraport", "yunhorn_kgl_l_v1", "1"],
	for _, i := range conf.DEVICES_LIST {
		// log.Println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&")
		// log.Println(i)
		if id == i[0] {
			data[0], data[1] = i[2], i[3]
			log.Println(data)
			break
		} else {
			data[0], data[1] = "null", "null"
		}
	}
	//log.Println("get_seat_device_data:", data)
	return data
}

// 从配置文件中匹配对应的数据
func scan_seat_from_confdata(T string, conf_data [][]interface{}) Seat_data {
	var data Seat_data
	//实例化空集合
	data.POSITIONLIST = make([]interface{}, 0)
	data.HASPERSONLIST = make([]interface{}, 0)
	for _, i := range conf_data {
		if i[0] == T {
			data.POSITIONLIST = append(data.POSITIONLIST, i[1])
			if len(i) < 3 {
				i = append(i, 0)
			}
			data.HASPERSONLIST = append(data.HASPERSONLIST, i[2])
			switch i[2] {
			case 0:
				data.EMPTYPOSITION++
			case 1:
				data.OCCUPYPOSITION++
			}
		}
	}
	return data
}

type WEATHER struct {
	SKYCON             string      `json:"skycon"`
	ICON_URL           string      `json:"icon_url"`
	O3                 float32     `json:"o3"`
	CO                 float32     `json:"co"`
	SO2                float32     `json:"so2"`
	NO2                float32     `json:"no2"`
	TEMPERATURE        float32     `json:"temperature"`
	HUMIDITY           float32     `json:"humidity"`
	PM25               float32     `json:"pm25"`
	PM10               float32     `json:"pm10"`
	CLOUDRATE          float32     `json:"cloudrate"`
	AQI                float32     `json:"aqi"`
	DSWRF              float32     `json:"dswrf"`
	VISIBILITY         float32     `json:"visibility"`
	ULTRAVIOLET_DESC   string      `json:"ultraviolet_desc"`
	PRES               float32     `json:"pres"`
	COMFORT_DESC       string      `json:"comfort_desc"`
	WIND_DIRECTION     float32     `json:"wind_direction"`
	WIND_SPEED         float32     `json:"wind_speed"`
	TEMPERATURE_INDOOR interface{} `json:"temperature_indoor"`
	HUMIDITY_INDOOR    interface{} `json:"humidity_indoor"`
}

// 获取天气情况api
func gw_weather_api(c *gin.Context) {
	DEVICEDATAS.RLock()
	rows, _ := db.Query("SELECT skycon, icon_url, o3, co, so2, no2, temperature,  humidity,  pm25, pm10, cloudrate, aqi, dswrf, visibility, ultraviolet_desc, pres, comfort_desc, wind_direction, wind_speed FROM weather order by id DESC limit 1")
	var data WEATHER
	rows.Next()
	rows.Scan(
		&data.SKYCON,
		&data.ICON_URL,
		&data.O3,
		&data.CO,
		&data.SO2,
		&data.NO2,
		&data.TEMPERATURE,
		&data.HUMIDITY,
		&data.PM25,
		&data.PM10,
		&data.CLOUDRATE,
		&data.AQI,
		&data.DSWRF,
		&data.VISIBILITY,
		&data.ULTRAVIOLET_DESC,
		&data.PRES,
		&data.COMFORT_DESC,
		&data.WIND_DIRECTION,
		&data.WIND_SPEED)
	rows.Close()
	var sum float32
	var toinitdata float32 = 0.0
	var data_buf = make(map[string]interface{})
	for _, i := range conf.DEVICES_LIST {
		if i[2] == "yunhorn_kq_c_v1" {
			sum++
			for k, j := range DEVICEDATAS.DATA[i[2]+"_"+i[3]].DATA {
				if j != nil {
					data_buf[k] = toinitdata
					data_buf[k] = (data_buf[k].(float32) + j.(float32)) / sum
				}
			}
		}
	}
	data.TEMPERATURE_INDOOR = data_buf["温度"]
	data.HUMIDITY_INDOOR = data_buf["湿度"]
	DEVICEDATAS.RUnlock()
	c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": data})
}