YHGW/router.go

837 lines
22 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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("/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 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 = 1010
R_data.ID = "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]))
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)
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("nh3",nh3data)
log.Println("h2s",data[13])
buffer = new(bytes.Buffer)
ch2o1 := strconv.Itoa(int(data[14]))
buffer.WriteString(ch2o1)
buffer.WriteString(".")
ch2o2 := strconv.Itoa(int(data[15]))
if int64(data[15])<10{
buffer.WriteString("0")
}
buffer.WriteString(ch2o2)
ch2o := buffer.String()
// 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"]=data[13]
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 采集器配置信息
// log.Println("DEVICEDATAS.data:",DEVICEDATAS.DATA)
for _, i := range conf.GATEWAY_INFO.CONFIG {
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})
}