404 lines
11 KiB
Go
404 lines
11 KiB
Go
package main
|
|
|
|
import (
|
|
"github.com/gin-contrib/cors"
|
|
"github.com/gin-gonic/gin"
|
|
_ "github.com/mattn/go-sqlite3"
|
|
"log"
|
|
"math"
|
|
"net/http"
|
|
"strconv"
|
|
)
|
|
|
|
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.GET("/test/:id", test_api)
|
|
v1.GET("/test2/:id", test_api2)
|
|
|
|
}
|
|
router.Run(":10086")
|
|
}
|
|
|
|
// 厕位占用api
|
|
func test_api(c *gin.Context) {
|
|
DEVICEDATAS.RLock()
|
|
//type_id := c.Param("id")
|
|
|
|
var device Device
|
|
device.Lock()
|
|
device.ID = demoDevice.ID
|
|
device.VERSION = demoDevice.VERSION
|
|
device.ONLINE = demoDevice.ONLINE
|
|
device.DATA = make(map[string]interface{})
|
|
device.DATA["data7"] = 1
|
|
device.Unlock()
|
|
DEVICEDATAS.DATA[demoDevice.VERSION+"_1"] = device
|
|
|
|
c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "ok"})
|
|
}
|
|
|
|
// 厕位占用api
|
|
func test_api2(c *gin.Context) {
|
|
DEVICEDATAS.RLock()
|
|
//type_id := c.Param("id")
|
|
|
|
var device Device
|
|
device.Lock()
|
|
device.ID = demoDevice.ID
|
|
device.VERSION = demoDevice.VERSION
|
|
device.ONLINE = demoDevice.ONLINE
|
|
device.DATA = make(map[string]interface{})
|
|
device.DATA["data7"] = 0
|
|
device.Unlock()
|
|
DEVICEDATAS.DATA[demoDevice.VERSION+"_1"] = device
|
|
|
|
c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "ok"})
|
|
}
|
|
|
|
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)
|
|
//}
|
|
|
|
if DEVICEDATAS.DATA[version+"_"+num].DATA["data"+strconv.Itoa(k+1)] != nil {
|
|
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
|
|
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})
|
|
}
|