package main import ( "bytes" "encoding/json" "io/ioutil" "log" "math" "net" "net/http" "strconv" "sync" "time" "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" _ "github.com/mattn/go-sqlite3" ) 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("/getConf") v1.GET("/writeCommand", writeCommand) } router.LoadHTMLGlob("static/*") opsV1 := router.Group("/ops/v1") { opsV1.GET("/index", func(c *gin.Context) { c.HTML(http.StatusOK, "index.html", gin.H{ "title": "hello Go", }) }) } 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"` } func writeCommand(c *gin.Context) { // var heartbeat []byte = []byte{0x01} addr := c.Query("addr") command := c.Query("command") // commandInt,err := strconv.Atoi(command) // if err !=nil{ // c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "msg": "command"}) // return; // } commands := []byte(command) byteAddr, ok := sensorMap.Load(addr) if !ok { c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "msg": "valid addr"}) return } loraNode, ok := loraNodeMap.Load(addr) if !ok { c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "msg": "valid addr"}) return } commands = []byte{0x01} if command == "1" { commands = []byte{0x01} } else if command == "2" { commands = []byte{0x02} } else { c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "msg": "valid command"}) return } // strconv.Itoa var buffer bytes.Buffer buffer.Write(byteAddr.([]byte)) // log.Println(commands) buffer.Write(commands) log.Println("loragws ", loraNode.(LoraNode).LORA_GWS) for _, loragwip := range loraNode.(LoraNode).LORA_GWS { loraconn, ok := loragwMap.Load(loragwip) if ok { log.Println("=======================begin push tcp command ", buffer.Bytes()) _, err := loraconn.(net.Conn).Write(buffer.Bytes()) if err != nil { log.Println("write msg error!", err) c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "msg": "fail"}) return } } else { } } log.Println(addr) log.Println(command) log.Println("will send commands ", commands) c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "msg": "success"}) } var dparkConf DparkConf var connTest net.Conn //获取数据防抖配置时间 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 } // time. extensionInTime = dparkConf.ExtensionInTime extensionOutTime = dparkConf.ExtensionOutTime // check(err) } //距离有效判断time. 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, loragwip string) 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] if datatype == 0 { var R_data P1004_6 R_data.CODE = 1008 R_data.ID = adr //尿布台 R_data.VERSION = "sts_hps_3ir" R_data.ONLINE = true R_data.DATA = make(map[string]interface{}) R_data.DATA["restart"] = data[6] data_bufTmp, _ := json.Marshal(R_data) data_buf := string(data_bufTmp) go post_to_server(data_buf) } else if datatype == 1 || datatype == 2 { //dpark 1-尿布台 2-吸顶 //过滤无效数据 adr cs2001 := data[6] var R_data P1004_6 R_data.CODE = 1008 R_data.ID = adr //尿布台 R_data.VERSION = "sts_hps_3ir" R_data.ONLINE = true R_data.DATA = make(map[string]interface{}) R_data.DATA["cs2001"] = cs2001 R_data.DATA["data"] = 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 = "sts_lts_01" R_data.DATA["tof"] = tof tofTmp := strconv.FormatInt(int64(data[7]&0xff), 10) readyData.WriteString("*") readyData.WriteString(tofTmp) } R_data.TIMESTAMP = time.Now().UnixNano() / 1e6 data_bufTmp, _ := json.Marshal(R_data) data_buf := string(data_bufTmp) go post_to_server(data_buf) // log.Println("readyData:",readyData.String()) //默认当前无人占用 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 fail ", adr) 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 if !Contains(newLoraNode.LORA_GWS, loragwip) { newLoraNode.LORA_GWS = append(newLoraNode.LORA_GWS, loragwip) } 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 if !Contains(newLoraNode.LORA_GWS, loragwip) { newLoraNode.LORA_GWS = append(newLoraNode.LORA_GWS, loragwip) } 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 !Contains(newLoraNode.LORA_GWS, loragwip) { newLoraNode.LORA_GWS = append(newLoraNode.LORA_GWS, loragwip) } 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 = adr // "853c0000" //尿布台 R_data.VERSION = "yunhorn_door_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])) log.Println("aqdata|all:", data) 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("aqdata|wdfh",data[6]) wddata := buffer.String() // log.Println("aqdata|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("aqdata|sddata",sddata) buffer = new(bytes.Buffer) nh3int1 := strconv.Itoa(int(data[11])) buffer.WriteString(nh3int1) buffer.WriteString(".") nh3int2 := strconv.Itoa(int(data[12])) if int64(data[12]) < 10 { buffer.WriteString("0") } buffer.WriteString(nh3int2) nh3data := buffer.String() // log.Println("aqdata|nh3",nh3data) buffer = new(bytes.Buffer) h2sint1 := strconv.Itoa(int(data[13])) buffer.WriteString(h2sint1) buffer.WriteString(".") h2sint2 := strconv.Itoa(int(data[14])) if int64(data[14]) < 10 { buffer.WriteString("0") } buffer.WriteString(h2sint2) h2sdata := buffer.String() // log.Println("aqdata|h2s",h2sdata) buffer = new(bytes.Buffer) ch2o1 := strconv.Itoa(int(data[15])) buffer.WriteString(ch2o1) buffer.WriteString(".") ch2o2 := strconv.Itoa(int(data[16])) if int64(data[16]) < 10 { buffer.WriteString("0") } buffer.WriteString(ch2o2) ch2o := buffer.String() // ch2o := uint32(data[14])*256+uint32(data[15]) // log.Println("aqdata|ch2o",ch2o) co2data := uint32(data[17])*256 + uint32(data[18]) // log.Println("aqdata|co2data",co2data) tvocdata := data[19] // log.Println("aqdata|tvocdata",tvocdata) // log.Println("pm25data1",data[19]) // log.Println("pm25data2",data[20]) pm25data := uint32(data[20])*256 + uint32(data[21]) // log.Println("aqdata|pm25data",pm25data) // log.Println("pm10data1",data[21]) // log.Println("pm10data2",data[22]) pm10data := uint32(data[22])*256 + uint32(data[23]) // log.Println("aqdata|pm10data",pm10data) //wdfh log.Printf("aqdata|wddata|sddata|nh3data|h2sdata|ch2o|co2data|tvocdata|pm25data|pm10data") log.Printf("aqdata|%s|%s|%s|%s|%s|%d|%d|%d|%d", wddata, sddata, nh3data, h2sdata, ch2o, co2data, tvocdata, pm25data, pm10data) var R_data P1004_6 R_data.CODE = 1005 R_data.ID = adr // "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"] = h2sdata 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 "" } 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.Lock() if DEVICEDATAS.DATA != nil { _, ok := DEVICEDATAS.DATA[loraNode.DEVICE] if ok { DEVICEDATAS.DATA[loraNode.DEVICE].DATA[loraNode.LOCATION_DATA] = loraNode.CURRENT_DATA log.Println("yunhorndeug.push.data.change:", DEVICEDATAS.DATA[loraNode.DEVICE]) } else { log.Println("changeDataV2.DEVICEDATAS load not ok:", loraNode.DEVICE) } } else { log.Println("changeDataV2.DEVICEDATAS not init:", loraNode.DEVICE) } DEVICEDATAS.Unlock() // 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) { var rl_data EventNotificationAlert // var debugInt = 2 // if debugInt > 1 { // c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": rl_data}) // return // } err := c.Bind(&rl_data) if conf.DEBUG { log.Println(rl_data) } checkErr(err, false) // send_data(1004) var R_data P1004_6 R_data.CODE = 1004 R_data.ID = rl_data.MACADDRESS R_data.VERSION = "hk_kll_v1" R_data.ONLINE = true R_data.DATA = make(map[string]interface{}) R_data.DATA["starttime"] = rl_data.PEOPLECOUNTING.TIMERANGE.STARTTIME R_data.DATA["endtime"] = rl_data.PEOPLECOUNTING.TIMERANGE.ENDTIME R_data.DATA["enter"] = rl_data.PEOPLECOUNTING.ENTER R_data.DATA["pass"] = rl_data.PEOPLECOUNTING.PASS R_data.DATA["exit"] = rl_data.PEOPLECOUNTING.EXIT traffic_data.TRAFFIC = traffic_data.TRAFFIC + rl_data.PEOPLECOUNTING.ENTER data_buf, _ := json.Marshal(R_data) post_to_server(string(data_buf)) 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") //locationCode := c.Param("locationCode") var data Seat_data var conf_data [][]interface{} //conf.GATEWAY_INFO.CONFIG 采集器配置信息 // log.Println("DEVICEDATAS.data:",DEVICEDATAS.DATA) for _, i := range conf.GATEWAY_INFO.CONFIG { //if i.LOCATION_CODE != locationCode{ // continue //} arr := get_seat_device_data(i.ID) //获取到设备版本 version, num := arr[0], arr[1] if version == "null" || num == "null" { continue } if DEVICEDATAS.DATA[version+"_"+num].DATA != nil { log.Println("^^^^^^^^^^^^^^^^^^DEVICEDATAS.DATA-version_num", DEVICEDATAS.DATA[version+"_"+num]) for k, j := range i.DATA { //log.Println("@@@@@@@@@@@@@@@@@@@@@@@@@@,i.DATA-j",j) // log.Println("============================devicedatas.data:", DEVICEDATAS.DATA[version+"_"+num].DATA) if DEVICEDATAS.DATA[version+"_"+num].DATA["data"+strconv.Itoa(k+1)] != nil { //这里不会改变DEVICEDATAS.DATA的数据,只是判断一下有没有数据,如果有,则加上 // 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("@@@@@@@@@@@@@@@@@@@@@@@@@@,i.DATA-j,appended.conf_data",conf_data) } } } 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 { if id == i[0] { data[0], data[1] = i[2], i[3] log.Println("get_seat_device_data", 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 { //T 男厕位 女厕位 //conf_data [[男厕位 1],[女厕位 1]] // 第一位是数据类型 第二位是位置 第三位是有无人占用 //conf_data [男厕位 1 0/1] //把当前符合类型的数据加入到返回集合中 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}) // }