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" "reflect" "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>(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, "超时") } } // interface转map[string]interface{} func ToMap(in interface{}, tagName string) (map[string]interface{}, error){ out := make(map[string]interface{}) v := reflect.ValueOf(in) if v.Kind() == reflect.Ptr { v = v.Elem() } if v.Kind() != reflect.Struct { // 非结构体返回错误提示 return nil, fmt.Errorf("ToMap only accepts struct or struct pointer; got %T", v) } t := v.Type() // 遍历结构体字段 // 指定tagName值为map中key;字段值为map中value for i := 0; i < v.NumField(); i++ { fi := t.Field(i) if tagValue := fi.Tag.Get(tagName); tagValue != "" { out[tagValue] = v.Field(i).Interface() } } return out, nil }