From 7a19301f6972e0b81490e57200a634e4e3731a4c Mon Sep 17 00:00:00 2001 From: zhangzengfei <zhangzengfei@smartai.com> Date: 星期四, 17 十月 2024 01:42:23 +0800 Subject: [PATCH] 完善rfid读取楼层 --- controller/nvcsCtl.go | 33 ++++++ config/config.go | 9 + rfid/rw.go | 77 ++++++++++++++- rfid/proto.go | 42 ++++++++ rfid/doc.go | 48 +++++++++ service/nvcs.go | 59 +++++++++-- 6 files changed, 249 insertions(+), 19 deletions(-) diff --git a/config/config.go b/config/config.go index b083bc0..4537ffa 100644 --- a/config/config.go +++ b/config/config.go @@ -69,10 +69,11 @@ } type rfid struct { - DevName string `mapstructure:"dev"` - Baud int `mapstructure:"baud"` - EPC string `mapstructure:"epc"` - Position uint8 `mapstructure:"position"` + DevName string `mapstructure:"dev"` + Baud int `mapstructure:"baud"` + ReadFloor bool `mapstructure:"read-floor"` + EPC string `mapstructure:"epc"` + Position uint8 `mapstructure:"position"` } type rateLimit struct { diff --git a/controller/nvcsCtl.go b/controller/nvcsCtl.go new file mode 100644 index 0000000..089d8fe --- /dev/null +++ b/controller/nvcsCtl.go @@ -0,0 +1,33 @@ +package controller + +import ( + "gat1400Exchange/service" + "github.com/gin-gonic/gin" + "net/http" +) + +type NVCSController struct { +} + +// 鏋勯�犲嚱鏁� +func NewNVCSController() SubPlatformController { + controller := SubPlatformController{} + + return controller +} + +func (n NVCSController) RunStatus(c *gin.Context) { + var runStatus = make(map[string]string, 0) + runStatus["floor"] = service.ElevatorRunFloor + + switch service.ElevatorRunState { + case 0: + runStatus["status"] = "鍋�" + case 1: + runStatus["status"] = "涓�" + case 2: + runStatus["status"] = "涓�" + } + + c.JSON(http.StatusOK, gin.H{"success": true, "data": runStatus, "msg": "ok"}) +} diff --git a/rfid/doc.go b/rfid/doc.go new file mode 100644 index 0000000..ce3e26b --- /dev/null +++ b/rfid/doc.go @@ -0,0 +1,48 @@ +package rfid + +/* +E250019506C06104002d3446 -4F +E250019506C06103002d3346 -3F +E250019506C06102002d3246 -2F +E250019506C06102002d3146 -1F +E250019506C0400100003146 1F +E250019506C0400200003246 2F +E250019506C0400300003346 3F +E250019506C0400400003446 4F +E250019506C0400500003546 5F +E250019506C0400600003646 6F +E250019506C0400700003746 7F +E250019506C0400800003846 8F +E250019506C0400900003946 9F +E250019506C0601000313046 10F +E250019506C0601100313146 11F +E250019506C0601200313246 12F +E250019506C0601300313346 13F +E250019506C0601400313446 14F +E250019506C0601500313546 15F +E250019506C0601600313646 16F +E250019506C0601700313746 17F +E250019506C0601800313846 18F +E250019506C0601900313946 19F +E250019506C0602000323046 20F +E250019506C0602100323146 21F +E250019506C0602200323246 22F +E250019506C0602300323346 23F +E250019506C0602400323446 24F +E250019506C0602500323546 25F +E250019506C0602600323646 26F +E250019506C0602700323746 27F +E250019506C0602800323846 28F +E250019506C0602900323946 29F +E250019506C0603000333046 30F +E250019506C0603100333146 31F +E250019506C0603200333246 32F +E250019506C0603300333346 33F +E250019506C0603400333446 34F +E250019506C0603500333546 35F +E250019506C0603600333646 36F +E250019506C0603700333746 37F +E250019506C0603800333846 38F +E250019506C0603900333946 39F +E250019506C0604000343046 40F +*/ diff --git a/rfid/proto.go b/rfid/proto.go index cbd59f8..10f208c 100644 --- a/rfid/proto.go +++ b/rfid/proto.go @@ -1,5 +1,47 @@ package rfid +import ( + "encoding/hex" + "fmt" + "strconv" + "strings" +) + const ( ControlWordEPCReadResponse6C uint32 = 0x00011200 ) + +func Parse2Floor(input string) (string, error) { + // 瀹氫箟鍓嶇紑 + prefix := "E250019506C" + + // 妫�鏌ュ瓧绗︿覆鏄惁鍖呭惈鎸囧畾鍓嶇紑 + if !strings.HasPrefix(input, prefix) { + return "", fmt.Errorf("瀛楃涓叉病鏈変互鎸囧畾鍓嶇紑 %s 寮�濮�", prefix) + } + + // 鎻愬彇闀垮害閮ㄥ垎鐨勫瓧绗︿覆骞惰浆鎹㈡垚鏁存暟 + lengthStr := input[len(prefix) : len(prefix)+2] + length, err := strconv.Atoi(lengthStr) + if err != nil { + return "", fmt.Errorf("闀垮害瑙f瀽閿欒: %v", err) + } + + //fmt.Println("data len ", length) + + // 鑾峰彇鏈熬鐨勫瓧绗︼紝鎸夌収鎸囧畾闀垮害杩涜鎴彇 + if len(input) < len(prefix)+2+length { // 姣忎釜瀛楃鏄�2涓崄鍏繘鍒跺瓧绗﹁〃绀� + return "", fmt.Errorf("瀛楃涓查暱搴︿笉瓒�") + } + + hexSection := input[len(input)-length:] + + // 灏嗗崄鍏繘鍒跺瓧绗︿覆杞崲涓哄瓧鑺傛暟缁� + bytes, err := hex.DecodeString(hexSection) + if err != nil { + return "", fmt.Errorf("鍗佸叚杩涘埗瑙f瀽閿欒: %v", err) + } + + // 灏嗗瓧鑺傛暟缁勮浆鎹负瀛楃涓� + return string(bytes), nil +} diff --git a/rfid/rw.go b/rfid/rw.go index 79d95d2..3761e90 100644 --- a/rfid/rw.go +++ b/rfid/rw.go @@ -1,9 +1,11 @@ package rfid import ( + "context" "encoding/binary" "encoding/hex" "fmt" + "io" "time" "github.com/tarm/serial" @@ -18,10 +20,12 @@ } type Reader struct { - DevName string - Baud int - ReadDuration int - DevPort *serial.Port + DevName string + Baud int + ReadDuration int + EPCData string + ReadTimestamp int64 + DevPort *serial.Port } func (r *Reader) OpenSerial() (err error) { @@ -95,7 +99,6 @@ for { select { case <-stop: - fmt.Println("璇诲彇宸茶秴鏃�") return false, nil default: for i := 0; i < 1024; i++ { @@ -153,3 +156,67 @@ } } } + +func (r *Reader) ReadEPCData(ctx context.Context) error { + err := r.StartAutoRead() + if err != nil { + return err + } + + // 鏍规嵁鍗忚鏈�澶ф暟鎹暱搴﹁皟鏁寸紦鍐插尯 + buf := make([]byte, 1024) + for { + select { + case <-ctx.Done(): + return nil + default: + for i := 0; i < 1024; i++ { + buf[i] = 0 // 娓呴浂鎴栧叾浠栧鐞� + } + + n, err := r.DevPort.Read(buf) + if err != nil && err != io.EOF { + return err + } + + if n == 0 || n < 8 { + continue // 濡傛灉娌℃湁璇诲彇鍒版暟鎹� + } + + // 妫�鏌ュ抚澶� + if buf[0] != 0x5A { + continue // 蹇界暐閿欒甯� + } + fmt.Printf("Read message %x\n", buf[:n]) // 鎵撳嵃鍗忚鎺у埗瀛楄繘琛岃皟璇� + + // 鏍¢獙CRC + //fmt.Printf("Crc %x\n",buf[n-2 : n]) + receivedCrc := binary.BigEndian.Uint16(buf[n-2 : n]) + computedCrc := CRC16XMODEM(buf[1 : n-2]) + if receivedCrc != (computedCrc & 0xFFFF) { + fmt.Println("CRC check failed") + continue + } + + // 瑙f瀽鍗忚鎺у埗瀛� (浠呭湪闇�瑕佹椂浣跨敤) + //fmt.Printf("Control Word: %x\n", buf[1:5]) // 鎵撳嵃鍗忚鎺у埗瀛楄繘琛岃皟璇� + + controlWord := binary.BigEndian.Uint32(buf[1:5]) + if controlWord != ControlWordEPCReadResponse6C { + fmt.Printf("Control Word: %d, rec word %d\n", ControlWordEPCReadResponse6C, controlWord) + continue + } + + // 瑙f瀽EPC鏁版嵁闀垮害 + epcLength := binary.BigEndian.Uint16(buf[7:9]) + //fmt.Printf("EPC length %d, EPC %x \n", epcLength, buf[9:9+epcLength]) + + // 鍥炶皟浼犻�乪pc鏁版嵁 + //callBack(buf[9 : 9+epcLength]) + r.EPCData = fmt.Sprintf("%X", buf[9:9+epcLength]) + r.ReadTimestamp = time.Now().Unix() + + fmt.Printf("read epc %s\n", r.EPCData) + } + } +} diff --git a/service/nvcs.go b/service/nvcs.go index d7579ce..848ebcd 100644 --- a/service/nvcs.go +++ b/service/nvcs.go @@ -2,6 +2,7 @@ import ( "bytes" + "context" "encoding/binary" "encoding/hex" "encoding/json" @@ -73,6 +74,7 @@ ) var ElevatorRunState int +var ElevatorRunFloor string var RunningCorrectTaskId string func A1CorrectFloor() { @@ -185,7 +187,28 @@ logger.Info("UDP server listening on port %s...", port) + rfidReader := rfid.NewReader(config.RFIDConf.DevName, 115200, 5) + if config.RFIDConf.ReadFloor { + defer rfidReader.CloseSerial() + + err := rfidReader.OpenSerial() + if err != nil { + logger.Error("open rfid. %s", err.Error()) + return + } + + ctx, _ := context.WithCancel(context.Background()) + + go func() { + err := rfidReader.ReadEPCData(ctx) + if err != nil { + logger.Error("rfid read. %s", err.Error()) + } + }() + } + var lastFloor int + var lastSaveTime int64 // 鏃犻檺寰幆绛夊緟鎺ユ敹鏁版嵁 for { // 鍒涘缓涓�涓紦鍐插尯鏉ュ瓨鍌ㄦ帴鏀剁殑鏁版嵁 @@ -239,27 +262,38 @@ } // correct floor when elevator stopped. - if elevator.Status.RunDir == 0 { - go A1CorrectFloor() - } else { - RunningCorrectTaskId = "" - if lastFloor == elevator.Status.Floor { - continue - } + //if elevator.Status.RunDir == 0 { + // go A1CorrectFloor() + //} else { + // RunningCorrectTaskId = "" + //} + + if lastFloor == elevator.Status.Floor && (time.Now().Unix()-lastSaveTime < 2) { + continue } + lastFloor = elevator.Status.Floor + lastSaveTime = time.Now().Unix() // 绋嬪簭閮ㄧ讲鍦ㄨ澶囩, 瀛楃鍙犲姞鍣ㄤ笂鎶ョ殑鍚嶇О鍏佽涓虹┖. 鍦ㄤ簯绔�, 鍚嶇О蹇呴』涓庢憚鍍忔満鐩稿悓 if elevator.Name == "" { elevator.Name = "1" } - lastFloor = elevator.Status.Floor + ElevatorRunState = elevator.Status.RunDir + ElevatorRunFloor = elevator.Status.FloorName + if config.RFIDConf.ReadFloor && rfidReader.EPCData != "" { + ElevatorRunFloor, _ = rfid.Parse2Floor(rfidReader.EPCData) + + if ElevatorRunFloor != elevator.Status.FloorName { + logger.Warn("rfid epc %s, nvcs floor %s", ElevatorRunFloor, elevator.Status.FloorName) + } + } go func() { var d = models.Positions{ DeviceId: elevator.Name, - Pos: elevator.Status.FloorName, - RunDir: elevator.Status.RunDir, + Pos: ElevatorRunFloor, + RunDir: ElevatorRunState, CreateTime: time.Now().Unix(), TimeString: time.Now().Format("2006-01-02 15:04:05"), } @@ -364,6 +398,9 @@ iRunState = RunDown } + ElevatorRunState = iRunState + ElevatorRunFloor = req.State.Floor + //// 宸插埌鏈�涓嬪眰 //if req.State.Floor == A2BottomFloor { // runState = "涓�" @@ -430,6 +467,8 @@ } iRunState = req.Status + ElevatorRunState = req.Status + ElevatorRunFloor = fmt.Sprintf("%dF", req.Floor) logger.Debug("Received A2 report data %+v", req) // 璁板綍鐢垫杩愯鐘舵�� -- Gitblit v1.8.0