837 lines
22 KiB
Go
837 lines
22 KiB
Go
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})
|
||
}
|