diff --git a/conf/gateway.conf b/conf/gateway.conf index 2346668..c2573a1 100644 --- a/conf/gateway.conf +++ b/conf/gateway.conf @@ -6,86 +6,18 @@ "单位": "深圳市云兴科技", "config": [ { - "id": "deb03e28-ddcb-4e5d-aa31-d870a1f0f09b", + "id": "8E146028-E1B1-4AC9-8F47-01376A22CB35", "version": "yunhorn_kgl_c8_v1", "data": [ - ["女厕位", 1], - ["女厕位", 2], - ["女厕位", 3], - ["女厕位", 4], - ["女厕位", 5], - ["女厕位", 6], - ["男厕位", 1], - ["男厕位", 2] + ["女厕位", 1] ] }, { - "id": "EC13C2D9-6A93-4894-BB5B-89BDAA786D8A", + "id": "7BB22E6A-ED0D-4161-8370-6B722D3683B7", "version": "yunhorn_kgl_c8_v1", "data": [ - ["男厕位", 7], - ["男厕位", 8], - ["男厕位", 3], - ["男厕位", 4], - ["男厕位", 5], - ["男厕位", 6], - ["纸巾卷", 7], - ["纸巾抽", 8] - ] - }, { - "id": "82BF7B5E-EC0D-4DB6-807F-B097C3C84073", - "version": "yunhorn_kgl_c8_v1", - "data": [ - ["母婴", 1], - ["残卫", 1], - ["残卫", 2], - ["男便池", 4], - ["男便池", 5], - ["男便池", 6], - ["男便池", 7], - ["男便池", 8] - ] - }, { - "id": "F5B7FDCC-79A8-499E-A925-F2FF357BE30D", - "version": "yunhorn_kgl_c8_v1", - "data": [ - ["男厕位", 9], - ["男厕位", 10], - ["女厕位", 14], - ["女厕位", 15], - ["女厕位", 16], - ["女厕位", 17], - ["女厕位", 18], - [null, null] - ] - }, - { - "id": "00DD66A6-378E-450D-98AA-44AC02741980", - "version": "yunhorn_kgl_c16_v1", - "data": [ - ["女厕位", 1], - ["女厕位", 2], - ["女厕位", 3], - ["女厕位", 4], - ["女厕位", 5], - ["女厕位", 6], - ["女厕位", 7], - ["女厕位", 8], - ["女厕位", 9], - ["女厕位", 10], - ["女厕位", 11], - ["女厕位", 12], - ["女厕位", 13], - ["男便池", 1], - ["男便池", 2], - ["男便池", 3] - ] - }, - { - "id": "4E5D52DD-EB81-43C0-A2B6-04E432412EBA", - "version": "yunhorn_kgl_l_v1", - "data": [ - ["纸巾卷", 1] + ["男厕位", 1], + ["男厕位", 2] ] } ] @@ -118,8 +50,9 @@ ], "devices_list": [ ["4E5D52DD-EB81-43C0-A2B6-04E432412EBA", "loraport", "yunhorn_kgl_l_v1", "1"], - ["EB5B0798-9B7F-474E-AAB8-467FD5FE1293", "loraport", "yunhorn_kgl_l_v1", "2"], - ["deb03e28-ddcb-4e5d-aa31-d870a1f0f09b", "loraport", "yunhorn_kgl_c8_v1", "1"] + ["deb03e28-ddcb-4e5d-aa31-d870a1f0f09b", "loraport", "yunhorn_kgl_c8_v1", "1"], + ["7BB22E6A-ED0D-4161-8370-6B722D3683B7", "loraport", "yunhorn_kgl_c8_v1", "2"], + ["8E146028-E1B1-4AC9-8F47-01376A22CB35", "loraport", "yunhorn_kgl_c8_v1", "3"] ], "serialports_list": { "loraport": { @@ -160,41 +93,6 @@ "command": [ [3, 2, 0, 0, 0, 16, 120, 36] ] - }, - "52A79B3D-D9D9-48AF-AEB4-7D456BA22B31": { - "version": "yunhorn_db_c_v1", - "num": "1", - "command": [ - [104, 65, 4, 0, 120, 16, 68, 104, 17, 4, 51, 51, 52, 51, 195, 22] - ] - }, - "607E11C4-8986-4F8E-807E-FFA655A6F677": { - "version": "yunhorn_sb_c_v1", - "num": "1", - "command": [ - [104, 16, 103, 19, 146, 128, 1, 0, 0, 1, 3, 31, 144, 2, 186, 22] - ] - }, - "066BB944-AFA2-4E5D-86FA-61D9080A97BB": { - "version": "yunhorn_kq_c_v1", - "num": "1", - "command": [ - [2, 3, 0, 0, 0, 7, 4, 59] - ] - }, - "22E175B2-8DD5-4740-B428-0297F409AA47": { - "version": "yunhorn_lhq_c_v1", - "num": "1", - "command": [ - [4, 3, 0, 6, 0, 1, 100, 94] - ] - }, - "20F44B9C-E4A1-478E-B28F-0B7B14A2AF64": { - "version": "yunhorn_aq_c_v1", - "num": "1", - "command": [ - [3, 3, 0, 0, 0, 1, 133, 232] - ] } }, "loradevices_list": { @@ -210,5 +108,7 @@ "websocketurl": ["192.168.3.216:8080", "/echo"], "post_to_server": "https://smartoilets.cn/socketServer/statis/push", "debug": true, - "openserial":false + "openserial":false, + "open_tcp_server":false, + "check_serial":true } diff --git a/loadconfig.go b/loadconfig.go index 81a4bcb..e93df7f 100644 --- a/loadconfig.go +++ b/loadconfig.go @@ -75,10 +75,16 @@ var conf Conf var DEVICEDATAS Devicedatas var demoDevice Device +var femaledemoDevice Device +var maledemoDevice Device + var db, _ = sql.Open("sqlite3", "./db/gateway.db") // 加载配置文件 func init() { + + time.Now() + configfile, err := os.Open("conf/gateway.conf") check(err) defer configfile.Close() @@ -115,17 +121,36 @@ func init() { log.Println("init demoDevice success:", demoDevice) var device2 Device - device2.Lock() - device2.ID = demoDevice.ID - device2.VERSION = demoDevice.VERSION - device2.ONLINE = demoDevice.ONLINE - device2.DATA = make(map[string]interface{}) + device2.Lock() + device2.ID = demoDevice.ID + device2.VERSION = demoDevice.VERSION + device2.ONLINE = demoDevice.ONLINE + device2.DATA = make(map[string]interface{}) - device2.DATA["data7"] = 0 - device2.DATA["data8"] = 0 - - device2.Unlock() - DEVICEDATAS.DATA[demoDevice.VERSION+"_1"] = device2 + device2.DATA["data7"] = 0 + device2.DATA["data8"] = 0 + + device2.Unlock() + //DEVICEDATAS.DATA[demoDevice.VERSION+"_1"] = device2 + + femaledemoDevice.ID = "8E146028-E1B1-4AC9-8F47-01376A22CB35" + femaledemoDevice.VERSION = "yunhorn_kgl_c8_v1" + femaledemoDevice.DATA = make(map[string]interface{}) + femaledemoDevice.ONLINE = true + femaledemoDevice.DATA["data1"] = 0 + + //3是男厕 + DEVICEDATAS.DATA[demoDevice.VERSION+"_3"] = femaledemoDevice + + //2是女厕 配置演示使用 + maledemoDevice.ID = "7BB22E6A-ED0D-4161-8370-6B722D3683B7" + maledemoDevice.VERSION = "yunhorn_kgl_c8_v1" + maledemoDevice.DATA = make(map[string]interface{}) + maledemoDevice.ONLINE = true + maledemoDevice.DATA["data1"] = 0 + maledemoDevice.DATA["data2"] = 0 + //3是男厕 + DEVICEDATAS.DATA[demoDevice.VERSION+"_2"] = maledemoDevice dbdata_init() diff --git a/main.go b/main.go index 6858c76..27406c1 100644 --- a/main.go +++ b/main.go @@ -14,6 +14,8 @@ func main() { go serial_run() c := cron.New() send_data(1001) + //获取数据防抖处理时间 + go getConf() c.AddFunc("0, *, *, *, *, *", func() { send_data(1001) }) @@ -23,6 +25,10 @@ func main() { // log.Println(string(build_data(1001,devices))) }) + c.AddFunc("*/30, *, *, *, *, *", func() { + getConf() + }) + c.AddFunc("0, */10, *, *, *, *", savedata_cron) c.AddFunc("0, 0, 0, *, *, *", insertdata) c.AddFunc("0, 0, *, *, *, *", get_weather) diff --git a/router.go b/router.go index 76ed9d9..80968d0 100644 --- a/router.go +++ b/router.go @@ -1,13 +1,18 @@ 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" ) var router = gin.Default() @@ -27,47 +32,344 @@ func gw_router() { 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) + v1.POST("/push", push) + + v1.GET("/getConf") } 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"}) +type DparkConf struct { + ExtensionInTime int `json:"in"` + ExtensionOutTime int `json:"out"` } -// 厕位占用api -func test_api2(c *gin.Context) { - DEVICEDATAS.RLock() - //type_id := c.Param("id") +var dparkConf DparkConf - 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 +//获取数据防抖配置时间 +func getConf() { + resp, err := http.Get("http://localhost:8082/dpark/getConf") + if err != nil { + // handle error + log.Println("getConf.get.err", err) + return + } - c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "ok"}) + 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 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 = 10 + +var oldData1 = "" + +var oldData2 = "" + +var oldData3 = "" + +var dataMap sync.Map + +//接收传感器push来的数据,解析并上传到云端 +func push(c *gin.Context) { + + nowtime := time.Now() + + data := c.PostForm("d") + + log.Println("yunhorndeug.push.data|", data) + + go pushCODE1007(data) + + alldata := strings.Split(data, "#") + + if len(alldata) != 2 { + c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "ok"}) + return + } else { + + valuedata := strings.Split(alldata[1], "*") + + if len(valuedata) < 1 { + c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "ok"}) + return + } + + dtype, error := strconv.Atoi(valuedata[0]) + if error != nil { + c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "errtype"}) + return + } + + var nowTmpData = "1#0" + + if dtype == 1 { + if len(valuedata) != 3 { + c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "valuedata not 3"}) + return + } + addr, error := strconv.Atoi(alldata[0]) + if error != nil { + c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "erraddr"}) + return + } + cs2001, error := strconv.Atoi(valuedata[1]) + if error != nil { + c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "errcs2001"}) + return + } + + tof, error := strconv.Atoi(valuedata[2]) + if error != nil { + c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "errtof"}) + return + } + + if addr == 1 { + + if cs2001 == 1 || tof < 1650 { + nowTmpData = "1#1" + } + + if oldData1 != nowTmpData { + dataMap.Store(addr, nowtime) + if oldData1 == "" { + //为空 直接改变状态 + maledemoDevice.DATA["data1"] = 0 + if nowTmpData == "1#1" { + maledemoDevice.DATA["data1"] = 1 + } + changeData(2, maledemoDevice) + } + //存储状态 + oldData1 = nowTmpData + + } else { + oldDevDataTime, ok := dataMap.Load(addr) + if !ok { + log.Println("load time err", ok) + } + + if ok { + if oldDevDataTime != nil { + //log.Println("t2.Sub(t1)", nowtime.Sub(oldDevDataTime.(time.Time))) + + var duration = nowtime.Sub(oldDevDataTime.(time.Time)).Seconds() + var durationAsInt64 = int(duration) + + log.Printf("yunhorndebug.origin.%s|%s|%d|%d|%d|%d|%d", oldData1, nowTmpData, addr, dtype, cs2001, tof, durationAsInt64) + + if nowTmpData == "1#0" { + if durationAsInt64 < extensionOutTime { + c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "not enough time"}) + return + } + } else { + if durationAsInt64 < extensionInTime { + c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "not enough time"}) + return + } + } + maledemoDevice.DATA["data1"] = 0 + if nowTmpData == "1#1" { + maledemoDevice.DATA["data1"] = 1 + } + + changeData(2, maledemoDevice) + dataMap.Delete(addr) + } + } + } + + } else if addr == 2 { + if cs2001 == 1 || tof < 1650 { + nowTmpData = "1#1" + } + + if oldData2 != nowTmpData { + dataMap.Store(addr, nowtime) + if oldData2 == "" { + //为空 直接改变状态 + maledemoDevice.DATA["data2"] = 0 + if nowTmpData == "1#1" { + maledemoDevice.DATA["data2"] = 1 + } + changeData(2, maledemoDevice) + } + //存储状态 + oldData2 = nowTmpData + + } else { + oldDevDataTime, ok := dataMap.Load(addr) + if !ok { + log.Println("load time err", ok) + } + + if ok { + if oldDevDataTime != nil { + //log.Println("t2.Sub(t1)", nowtime.Sub(oldDevDataTime.(time.Time))) + + var duration = nowtime.Sub(oldDevDataTime.(time.Time)).Seconds() + var durationAsInt64 = int(duration) + + log.Printf("yunhorndebug.origin.%s|%s|%d|%d|%d|%d|%d", oldData2, nowTmpData, addr, dtype, cs2001, tof, durationAsInt64) + + if nowTmpData == "1#0" { + if durationAsInt64 < extensionInTime { + c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "not enough time"}) + return + } + } else { + if durationAsInt64 < extensionOutTime { + c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "not enough time"}) + return + } + } + maledemoDevice.DATA["data2"] = 0 + if nowTmpData == "1#1" { + maledemoDevice.DATA["data2"] = 1 + } + + changeData(2, maledemoDevice) + dataMap.Delete(addr) + } + } + } + } + + } else if dtype == 2 { + //吸顶传感器 没有距离数据 + if len(valuedata) != 2 { + c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "valuedata not 2,type2"}) + return + } + addr, error := strconv.Atoi(alldata[0]) + if error != nil { + c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "erraddr"}) + return + } + cs2001, error := strconv.Atoi(valuedata[1]) + if error != nil { + c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "errcs2001"}) + return + } + + if cs2001 == 1 { + nowTmpData = "1#1" + } + + if oldData3 != nowTmpData { + dataMap.Store(addr, nowtime) + if oldData3 == "" { + //为空 直接改变状态 + femaledemoDevice.DATA["data1"] = 0 + if nowTmpData == "1#1" { + femaledemoDevice.DATA["data1"] = 1 + } + changeData(2, maledemoDevice) + } + //存储状态 + oldData3 = nowTmpData + + } else { + oldDevDataTime, ok := dataMap.Load(addr) + if !ok { + log.Println("load time err", ok) + } + + if ok { + if oldDevDataTime != nil { + //log.Println("t2.Sub(t1)", nowtime.Sub(oldDevDataTime.(time.Time))) + + var duration = nowtime.Sub(oldDevDataTime.(time.Time)).Seconds() + var durationAsInt64 = int(duration) + + var tof = 0 + + log.Printf("yunhorndebug.origin.%s|%s|%d|%d|%d|%d|%d", oldData3, nowTmpData, addr, dtype, cs2001, tof, durationAsInt64) + + if nowTmpData == "1#0" { + if durationAsInt64 < extensionInTime { + c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "not enough time"}) + return + } + } else { + if durationAsInt64 < extensionOutTime { + c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": "not enough time"}) + return + } + } + + femaledemoDevice.DATA["data1"] = 0 + if nowTmpData == "1#1" { + femaledemoDevice.DATA["data1"] = 1 + } + changeData(3, femaledemoDevice) + dataMap.Delete(addr) + } + } + } + } + + } + + log.Println("data:", data) + c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": data}) +} + +//发送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 } type EventNotificationAlert struct { @@ -263,7 +565,9 @@ func seat_api(c *gin.Context) { // 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)]) } } @@ -271,7 +575,7 @@ func seat_api(c *gin.Context) { } } - //log.Println("end conf.data:", conf_data) + log.Println("end conf.data:", conf_data) switch type_id { case "1": @@ -313,6 +617,9 @@ func get_seat_device_data(id string) []string { // 从配置文件中匹配对应的数据 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]) diff --git a/worker.go b/worker.go index 342bd46..fe481a6 100644 --- a/worker.go +++ b/worker.go @@ -172,7 +172,7 @@ func yunhorn_ys_l_v1(data_buf []byte) { }else{ device.DATA["data7"] = 0 } - + //device.DATA["data7"] = data_int[0] device.Unlock() DEVICEDATAS.DATA[demoDevice.VERSION+"_1"].DATA["data7"] = device.DATA["data7"]