|
@@ -0,0 +1,304 @@
|
|
|
+package comm
|
|
|
+
|
|
|
+import (
|
|
|
+ "encoding/hex"
|
|
|
+ "fmt"
|
|
|
+ "github.com/gin-gonic/gin"
|
|
|
+ "github.com/jacobsa/go-serial/serial"
|
|
|
+ "../pkg/app"
|
|
|
+ "../pkg/e"
|
|
|
+ "../pkg/setting"
|
|
|
+ "../routers/restful"
|
|
|
+ "log"
|
|
|
+ "net/http"
|
|
|
+ "time"
|
|
|
+ "unsafe"
|
|
|
+)
|
|
|
+
|
|
|
+//一个已经被关闭的channel不会阻塞,已经被关闭的channel会实时返回
|
|
|
+//goroutine退出,关闭done来进行广播
|
|
|
+var done = make(chan struct{})
|
|
|
+var Id = make(chan int)
|
|
|
+var timeout = make(chan int)
|
|
|
+var ReturnString = make(chan string)
|
|
|
+//判断done是否关闭,即是否执行goroutine退出
|
|
|
+func cancelled() bool {
|
|
|
+ select {
|
|
|
+ case <-done:
|
|
|
+ return true
|
|
|
+ default:
|
|
|
+ return false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func Int2Byte(data int)(ret []byte){
|
|
|
+ var len uintptr = unsafe.Sizeof(data)
|
|
|
+ ret = make([]byte, len)
|
|
|
+ var tmp int = 0xff
|
|
|
+ var index uint = 0
|
|
|
+ for index=0; index<uint(len); index++{
|
|
|
+ ret[index] = byte((tmp<<(index*8) & data)>>(index*8))
|
|
|
+ }
|
|
|
+ return ret
|
|
|
+}
|
|
|
+
|
|
|
+func OpenComm() {
|
|
|
+ var sum byte
|
|
|
+ var recLength,dataLength, state int
|
|
|
+ comtimeout := 0
|
|
|
+ buf := make([]byte, 32)
|
|
|
+ recbuf := make([]byte, 1)
|
|
|
+ //s_params := make([]interface{}, 1)
|
|
|
+ openSerial:
|
|
|
+ f, err := serial.Open(*setting.CommSetting)
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("Error opening serial port: ", err)
|
|
|
+ time.Sleep(1 * time.Second)
|
|
|
+ goto openSerial
|
|
|
+ }else {
|
|
|
+ log.Printf("[info] Serial %s is Started", setting.CommSetting.PortName)
|
|
|
+ if comtimeout==0 {
|
|
|
+ defer f.Close()
|
|
|
+ }
|
|
|
+ for {
|
|
|
+ sum = (0x55 + 0xAA + 0x06 + 0x01 + 0x03 + 0x01) & 0xFF
|
|
|
+ v := 0
|
|
|
+ if comtimeout==0 {
|
|
|
+ v, _ = <- Id
|
|
|
+ }
|
|
|
+
|
|
|
+ comtimeout = 0
|
|
|
+ cowidByte := Int2Byte(v)[:3]
|
|
|
+ sum = (sum + cowidByte[0] + cowidByte[1] + cowidByte[2]) & 0xFF
|
|
|
+ cowidByte = append(cowidByte, sum)
|
|
|
+ requestCowid := "55AA06010301" + hex.EncodeToString(cowidByte)
|
|
|
+
|
|
|
+ txData_, err := hex.DecodeString(requestCowid)
|
|
|
+ recLength = 0
|
|
|
+ state = 0
|
|
|
+ _, err = f.Write(txData_)
|
|
|
+
|
|
|
+ fmt.Println(hex.EncodeToString(txData_))
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("Error writing to serial port: ", err)
|
|
|
+ time.Sleep(1 * time.Second)
|
|
|
+ comtimeout = 1
|
|
|
+ goto openSerial
|
|
|
+ }
|
|
|
+ loop:
|
|
|
+ for {
|
|
|
+ select {
|
|
|
+ case <-timeout:
|
|
|
+ break loop
|
|
|
+ default:
|
|
|
+ n, err := f.Read(buf)
|
|
|
+ if err != nil {
|
|
|
+ //if err != io.EOF {
|
|
|
+ fmt.Println("Error reading from serial port: ", err)
|
|
|
+ time.Sleep(1 * time.Second)
|
|
|
+ comtimeout = 1
|
|
|
+ goto openSerial
|
|
|
+ //}
|
|
|
+ //break loop
|
|
|
+ } else if n > 0 {
|
|
|
+ buf = buf[:n]
|
|
|
+ for _, value := range buf {
|
|
|
+ switch state {
|
|
|
+ case 0: //头判断
|
|
|
+ if value == 0x55 {
|
|
|
+ state = 1
|
|
|
+ recLength = 1
|
|
|
+ recbuf = recbuf[:0]
|
|
|
+ recbuf = append(recbuf, (byte)(value&0xFF))
|
|
|
+ }
|
|
|
+ case 1: //头判断中
|
|
|
+ if value == 0xAA {
|
|
|
+ state = 2
|
|
|
+ recLength = 2
|
|
|
+ recbuf = append(recbuf, (byte)(value&0xFF))
|
|
|
+ } else {
|
|
|
+ state = 0
|
|
|
+ recLength = 0
|
|
|
+ }
|
|
|
+ case 2: //接收数据长度
|
|
|
+ state = 3
|
|
|
+ recLength = 3
|
|
|
+ dataLength = (int)(value + 4)
|
|
|
+ recbuf = append(recbuf, (byte)(value&0xFF))
|
|
|
+ case 3: //接收数据中
|
|
|
+ recbuf = append(recbuf, (byte)(value&0xFF))
|
|
|
+ recLength++
|
|
|
+ if recLength == dataLength {
|
|
|
+ fmt.Println(hex.EncodeToString(recbuf))
|
|
|
+ ReturnString <- hex.EncodeToString(recbuf)
|
|
|
+ state = 0
|
|
|
+ recLength = 0
|
|
|
+ break loop
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ time.Sleep(10 * time.Millisecond)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func saveData(ReceStr string,x int,y int) (string, error){
|
|
|
+ s_params := make([]interface{}, 0)
|
|
|
+ //bytelist, err := hex.DecodeString(ReturnS)
|
|
|
+ s_params = append(s_params, 1)
|
|
|
+ s_params = append(s_params, x)
|
|
|
+ s_params = append(s_params, y)
|
|
|
+ s_params = append(s_params, 1)
|
|
|
+ _, err := restful.ExecQuery("INSERT INTO `cps_m` (`barid`, `x`, `y`) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE barid = ?", s_params)
|
|
|
+ if err != nil {
|
|
|
+ return "", err
|
|
|
+ } else {
|
|
|
+ bytelist, err := hex.DecodeString(ReceStr)
|
|
|
+ rodecount := (int)((bytelist[2]-5)>>1)
|
|
|
+ s_params = s_params[1:3]
|
|
|
+ if rodecount>0{
|
|
|
+ for i := 0; i < rodecount; i++{
|
|
|
+ beaconname := (int)(bytelist[8+2*i])
|
|
|
+ rssi := (int)(bytelist[9+2*i])
|
|
|
+ s_params = s_params[:2]
|
|
|
+ s_params = append(s_params, beaconname)
|
|
|
+ s_params = append(s_params, rssi)
|
|
|
+ s_params = append(s_params, rssi)
|
|
|
+ _, err = restful.ExecQuery("INSERT INTO `cps_d`(`pid`,`beaconid`,`rssi`) "+
|
|
|
+ "SELECT (SELECT `id` FROM `cps_m` WHERE `x`=? AND `y`=?),?,? ON DUPLICATE KEY UPDATE rssi = ?", s_params)
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if err == nil{
|
|
|
+ return "成功保存", nil
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ return "没有收到数据", nil
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return "没有收到数据", nil
|
|
|
+}
|
|
|
+
|
|
|
+func savePointData(ReceStr string,limit int) (interface{}, error){
|
|
|
+ s_params := make([]interface{}, 1)
|
|
|
+ //bytelist, err := hex.DecodeString(ReturnS)
|
|
|
+ bytelist, err := hex.DecodeString(ReceStr)
|
|
|
+ rodecount := (int)((bytelist[2]-5)>>1)
|
|
|
+ low := (int)(bytelist[5])
|
|
|
+ mid := (int)(bytelist[6])
|
|
|
+ mid = mid<<8
|
|
|
+ high := (int)(bytelist[7])
|
|
|
+ high = high<<16
|
|
|
+ tagid := (int)(low|mid|high)
|
|
|
+ s_params[0] = tagid
|
|
|
+ if rodecount>0{
|
|
|
+ for i := 0; i < rodecount; i++{
|
|
|
+ beaconname := (int)(bytelist[8+2*i])
|
|
|
+ rssi := (int)(bytelist[9+2*i])
|
|
|
+ s_params = s_params[:1]
|
|
|
+ s_params = append(s_params, beaconname)
|
|
|
+ s_params = append(s_params, rssi)
|
|
|
+ s_params = append(s_params, rssi)
|
|
|
+ _, err = restful.ExecQuery(" INSERT INTO `cps_point`(`tagid`,`beaconid`,`rssi`) "+
|
|
|
+ " Values( ?, ?, ?) ON DUPLICATE KEY UPDATE rssi = ?", s_params)
|
|
|
+ if err != nil {
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if err == nil{
|
|
|
+ s_params = s_params[:2]
|
|
|
+ s_params[0] = tagid
|
|
|
+ s_params[1] = limit
|
|
|
+ resultdata, err := restful.QueryByMap(" SELECT AVG(X) X,AVG(Y) Y FROM ( "+
|
|
|
+ "SELECT `cps_m`.x,`cps_m`.y, SUM(ABS(`cps_d`.`rssi`-`cps_point`.`rssi`)) absrssi "+
|
|
|
+ "FROM `cps_d` JOIN `cps_point` ON `cps_d`.`beaconid`=`cps_point`.`beaconid` "+
|
|
|
+ "JOIN `cps_m` ON `cps_m`.`id`=`cps_d`.`pid` WHERE `cps_point`.`tagid`= ? "+
|
|
|
+ "GROUP BY `cps_m`.x,`cps_m`.y "+
|
|
|
+ "ORDER BY SUM(ABS(`cps_d`.`rssi`-`cps_point`.`rssi`)) "+
|
|
|
+ "LIMIT ?) AS d " , 0,0,s_params)
|
|
|
+ if err != nil {
|
|
|
+ return "", err
|
|
|
+ } else {
|
|
|
+ return resultdata, nil
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ return "没有收到数据", nil
|
|
|
+ }
|
|
|
+ return "没有收到数据", nil
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+func ProcessHttp(c *gin.Context) {
|
|
|
+ var (
|
|
|
+ appG = app.Gin{C: c}
|
|
|
+ )
|
|
|
+
|
|
|
+ id := 0//com.StrTo(c.Param("id")).MustInt()
|
|
|
+ x := 0//com.StrTo(c.Param("x")).MustInt()
|
|
|
+ y := 0//com.StrTo(c.Param("y")).MustInt()
|
|
|
+ Id <- id
|
|
|
+ select {
|
|
|
+ case ReturnS := <- ReturnString: //拿到锁
|
|
|
+ if x>=0 && y>=0{
|
|
|
+ returnData, err := saveData(ReturnS,x,y)
|
|
|
+ if err != nil{
|
|
|
+ appG.Response(http.StatusOK, e.ERROR, err.Error())
|
|
|
+ }else {
|
|
|
+ appG.Response(http.StatusOK, e.SUCCESS, returnData)
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ returnData, err := savePointData(ReturnS,1)
|
|
|
+ if err != nil{
|
|
|
+ appG.Response(http.StatusOK, e.ERROR, err.Error())
|
|
|
+ }else {
|
|
|
+ appG.Response(http.StatusOK, e.SUCCESS, returnData)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ case <-time.After(10 * time.Second): //超时5s
|
|
|
+ timeout <- 1
|
|
|
+ appG.Response(http.StatusOK, e.ERROR, "超时")
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func ProcessHttpCPS(c *gin.Context) {
|
|
|
+ var (
|
|
|
+ appG = app.Gin{C: c}
|
|
|
+ )
|
|
|
+
|
|
|
+ id := 0//com.StrTo(c.Param("id")).MustInt()
|
|
|
+ limit := 0//com.StrTo(c.Param("limit")).MustInt()
|
|
|
+ Id <- id
|
|
|
+ select {
|
|
|
+ case ReturnS := <- ReturnString: //拿到锁
|
|
|
+ {
|
|
|
+
|
|
|
+ returnData, err := savePointData(ReturnS, limit)
|
|
|
+ if err != nil{
|
|
|
+ appG.Response(http.StatusOK, e.ERROR, err.Error())
|
|
|
+ }else {
|
|
|
+ appG.Response(http.StatusOK, e.SUCCESS, returnData)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ case <-time.After(10 * time.Second): //超时5s
|
|
|
+ timeout <- 1
|
|
|
+ appG.Response(http.StatusOK, e.ERROR, "超时")
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+// 用于判断每年月份的天数
|
|
|
+func MonthDay(date string)(month string ,sumday string){
|
|
|
+ //date :=
|
|
|
+ return month,sumday
|
|
|
+}
|
|
|
+
|
|
|
+
|