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"
	"net"
)

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.GET("/pushtest",pushTest)
		v1.GET("/pushtest2",pushTest2)
		v1.GET("/pushtest3",pushTest3)


		v1.GET("/getConf")

	}

	api_port := strconv.Itoa(conf.APIPORT)

	router.Run(":"+api_port)
}

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

var dparkConf DparkConf

var connTest net.Conn

func pushTest(c *gin.Context){
	//
	var heartbeat []byte = []byte{0x8E,0x3C,0x00,0x00,0x52,0x46}
	v, err := connTest.Write(heartbeat)
	log.Println("send.msg.conn.RemoteAddr",connTest.RemoteAddr())
	log.Println("send.msg.conn.v",v)
	if err != nil {
		log.Println("write msg error!", err)
	}
	return
}

func pushTest2(c *gin.Context){
	//
	var heartbeat []byte = []byte{0x8E,0x3C,0x00,0x00,0x47,0x46}
	v, err := connTest.Write(heartbeat)
	log.Println("send.msg.conn.RemoteAddr",connTest.RemoteAddr())
	log.Println("send.msg.conn.v",v)
	if err != nil {
		log.Println("write msg error!", err)
	}
	return
}

func pushTest3(c *gin.Context){
	//
	var heartbeat []byte = []byte{0x8E,0x3C,0x00,0x00,0x59,0x46}
	v, err := connTest.Write(heartbeat)
	log.Println("send.msg.conn.RemoteAddr",connTest.RemoteAddr())
	log.Println("send.msg.conn.v",v)
	if err != nil {
		log.Println("write msg error!", err)
	}
	return
}

//获取数据防抖配置时间
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 = 15

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 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]

	//dpark 1-尿布台 2-吸顶
	if datatype==1 || datatype==2{

		//过滤无效数据 adr

		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)
		}
		R_data.TIMESTAMP=time.Now().Unix()

		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)
				}

				if (datatype==2  && (extensionInTime2<=0 || extensionOutTime2<=0)){
					newLoraNode.CURRENT_DATA = current
					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 && extensionOutTime2>0 {
								return ""
							}
						}else{
							if durationAsInt64 < extensionOutTime && extensionOutTime>0 {
								return ""
							}
						}

				}else{
					//类型2 吸顶
					if datatype==2{
						if durationAsInt64 < extensionInTime2 && extensionInTime2>0  {
							return ""
						}
					}else{
						if durationAsInt64 < extensionInTime && extensionInTime>0 {
							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

				if (datatype==2  && (extensionInTime2<=0 || extensionOutTime2<=0)){
					newLoraNode.CURRENT_DATA = current
					changeDataV2(newLoraNode)
				}

				loraNodeMap.Store(adr,newLoraNode)


			}
		}

	}else if datatype==3{
		var R_data P1004_6
		R_data.CODE = 1005
		R_data.ID = "dc390000"
		//尿布台
		R_data.VERSION = "yunhorn_kq_c_v1"
		R_data.ONLINE = true
		R_data.DATA = make(map[string]interface{})
		R_data.DATA["data"]=int64(data[6])
		data_bufTmp, _ := json.Marshal(R_data)
		data_buf := string(data_bufTmp)
		go post_to_server(data_buf)

	}else if datatype==4{
		buffer := new(bytes.Buffer)

		// log.Println("data[9]",int64(data[9]))
		// log.Println("data[10]",int64(data[10]))

		if data[6] == 0{
			buffer.WriteString("-")
		}

		wdint1 := strconv.FormatInt(int64(data[7]&0xff), 10)
		buffer.WriteString(wdint1)
		buffer.WriteString(".")
		wdfh := int(data[10])
		wdint2 := strconv.FormatInt(int64(data[8]&0xff), 10)
		if wdfh<10{
			buffer.WriteString("0")
		}
		buffer.WriteString(wdint2)

		log.Println("wdfh",data[6])

		wddata := buffer.String()
		log.Println("wddata",wddata)

		buffer = new(bytes.Buffer)

		sdint1 := strconv.FormatInt(int64(data[9]&0xff), 10)
		buffer.WriteString(sdint1)
		buffer.WriteString(".")
		sdint2 := strconv.FormatInt(int64(data[10]&0xff), 10)
		if wdfh<10{
			buffer.WriteString("0")
		}
		buffer.WriteString(sdint2)

		sddata := buffer.String()
		log.Println("sddata",sddata)

		nh3int1 := strconv.FormatInt(int64(data[11]&0xff), 10)
		buffer.WriteString(nh3int1)
		buffer.WriteString(".")
		nh3int2 := strconv.FormatInt(int64(data[12]&0xff), 10)
		if wdfh<10{
			buffer.WriteString("0")
		}
		buffer.WriteString(nh3int2)
		nh3data := buffer.String()

		log.Println("nh3",nh3data)
		log.Println("h2s",data[13])
		ch2o := uint32(data[14])*256+uint32(data[15])
		log.Println("ch2o",ch2o)
		co2data := uint32(data[16])*256+uint32(data[17])
		log.Println("co2data",co2data)

		tvocdata := data[18]
		log.Println("tvocdata",tvocdata)

		// log.Println("pm25data1",data[19])
		// log.Println("pm25data2",data[20])
		pm25data := uint32(data[19])*256+uint32(data[20])
		log.Println("pm25data",pm25data)

		// log.Println("pm10data1",data[21])
		// log.Println("pm10data2",data[22])
		pm10data := uint32(data[21])*256+uint32(data[22])
		log.Println("pm10data",pm10data)

		var R_data P1004_6
		R_data.CODE = 1005
		R_data.ID = "dc390000"
		//尿布台
		R_data.VERSION = "yunhorn_kq_c_v1"
		R_data.ONLINE = true
		R_data.DATA = make(map[string]interface{})
		R_data.DATA["temperature"]=wddata
		R_data.DATA["humidity"]=sddata

		R_data.DATA["nh3"]=nh3data
		R_data.DATA["h2s"]=sddata
		R_data.DATA["ch2o"]=ch2o
		R_data.DATA["co2"]=co2data
		R_data.DATA["tvoc"]=tvocdata
		R_data.DATA["pm25"]=pm25data
		R_data.DATA["pm10"]=pm10data

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

	}

	// 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.change:",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})
}