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