From c8a641dd784c071f83a0d90c35f617607fd0811b Mon Sep 17 00:00:00 2001
From: zhangzengfei <zhangzengfei@smartai.com>
Date: 星期日, 20 十月 2024 02:26:01 +0800
Subject: [PATCH] 修改楼层缓存为双向链表
---
rfid/rw.go | 234 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 221 insertions(+), 13 deletions(-)
diff --git a/rfid/rw.go b/rfid/rw.go
index fd2fc7b..4cb8d2d 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"
@@ -11,17 +13,22 @@
func NewReader(devName string, baud, readDuration int) *Reader {
return &Reader{
- DevName: devName,
- Baud: baud,
- ReadDuration: readDuration,
+ DevName: devName,
+ Baud: baud,
+ ReadTimeout: readDuration,
+ Alive: true,
+ HeartbeatTime: time.Now().Unix(),
}
}
type Reader struct {
- DevName string
- Baud int
- ReadDuration int
- DevPort *serial.Port
+ DevName string
+ Baud int
+ EPCData string
+ ReadTimeout int
+ Alive bool
+ HeartbeatTime int64
+ DevPort *serial.Port
}
func (r *Reader) OpenSerial() (err error) {
@@ -76,7 +83,10 @@
func (r *Reader) ReadResponse() (int, error) {
buf := make([]byte, 1024) // 鏍规嵁鍗忚鏈�澶ф暟鎹暱搴﹁皟鏁寸紦鍐插尯
- return r.DevPort.Read(buf)
+ n, err := r.DevPort.Read(buf)
+ fmt.Printf("Recive message %X\n", buf[:n])
+
+ return n, err
}
func (r *Reader) ScanSpecificEPC(target string, minCount int) (bool, error) {
@@ -87,7 +97,7 @@
defer r.StopAutoRead()
- stop := time.After(time.Duration(r.ReadDuration) * time.Second)
+ stop := time.After(time.Duration(r.ReadTimeout) * time.Second)
// 鏍规嵁鍗忚鏈�澶ф暟鎹暱搴﹁皟鏁寸紦鍐插尯
buf := make([]byte, 1024)
@@ -95,7 +105,6 @@
for {
select {
case <-stop:
- fmt.Println("璇诲彇宸茶秴鏃�")
return false, nil
default:
for i := 0; i < 1024; i++ {
@@ -115,7 +124,7 @@
if buf[0] != 0x5A {
continue // 蹇界暐閿欒甯�
}
- fmt.Printf("Recive message %x\n", buf[:n]) // 鎵撳嵃鍗忚鎺у埗瀛楄繘琛岃皟璇�
+ fmt.Printf("Recive message %X\n", buf[:n]) // 鎵撳嵃鍗忚鎺у埗瀛楄繘琛岃皟璇�
// 鏍¢獙CRC
//fmt.Printf("Crc %x\n",buf[n-2 : n])
@@ -141,14 +150,213 @@
// 鍥炶皟浼犻�乪pc鏁版嵁
//callBack(buf[9 : 9+epcLength])
- epcData := fmt.Sprintf("%x", buf[9:9+epcLength])
+ epcData := fmt.Sprintf("%X", buf[9:9+epcLength])
if epcData == target {
scanCount++
if scanCount > minCount {
return true, nil
}
}
- fmt.Printf("read epc %s, target epc: %s", epcData, target)
+
+ fmt.Printf("read epc %s, target epc: %s\n", epcData, target)
}
}
}
+
+func (r *Reader) ReadEPCData(ctx context.Context) error {
+ err := r.StartAutoRead()
+ if err != nil {
+ return err
+ }
+
+ go func() {
+ for {
+ err := r.SendAck()
+ if err != nil {
+ fmt.Println("send ack.", err.Error())
+ }
+ time.Sleep(30 * time.Second)
+
+ if time.Now().Unix()-r.HeartbeatTime > 120 {
+ r.Alive = false
+ }
+ }
+ }()
+
+ // 鏍规嵁鍗忚鏈�澶ф暟鎹暱搴﹁皟鏁寸紦鍐插尯
+ 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
+ receivedCrc := binary.BigEndian.Uint16(buf[n-2 : n])
+ computedCrc := CRC16XMODEM(buf[1 : n-2])
+ if receivedCrc != (computedCrc & 0xFFFF) {
+ fmt.Println("CRC check failed")
+ continue
+ }
+
+ r.HeartbeatTime = time.Now().Unix()
+ r.Alive = true
+
+ // 瑙f瀽鍗忚鎺у埗瀛�
+ controlWord := binary.BigEndian.Uint32(buf[1:5])
+
+ switch controlWord {
+ case ControlWordDeviceInfo:
+ parseDeviceInfo(buf)
+ case ControlWordEPCReadResponse6C:
+ // 瑙f瀽EPC鏁版嵁闀垮害
+ epcLength := binary.BigEndian.Uint16(buf[7:9])
+
+ r.EPCData = fmt.Sprintf("%X", buf[9:9+epcLength])
+
+ // 鍥炶皟浼犻�乪pc鏁版嵁
+ //callBack(buf[9 : 9+epcLength])
+
+ fmt.Printf("Read epc %s\n", r.EPCData)
+ }
+ }
+ }
+}
+
+func (r *Reader) GetPower() error {
+ cmd := "5A0001020200002959"
+ data, _ := hex.DecodeString(cmd)
+
+ _, err := r.DevPort.Write(data)
+ if err != nil {
+ return err
+ }
+
+ // todo parse response
+ r.ReadResponse()
+
+ return nil
+}
+
+func (r *Reader) SendAck() error {
+ cmd := "5A000101000000DCE5"
+ //cmd := "5A000111120004000000015FFB"
+ data, _ := hex.DecodeString(cmd)
+
+ _, err := r.DevPort.Write(data)
+ return err
+}
+
+func (r *Reader) SetPower(val int) error {
+ if val < 10 || val > 33 {
+ return fmt.Errorf("value out of range, must be between 0 and 255")
+ }
+
+ frame := []byte{0x5A, 0x00, 0x01, 0x02, 0x01, 0x00, 0x02, 0x01}
+ frame = append(frame, byte(val))
+
+ crc := CRC16XMODEM(frame[1:])
+ crcBytes := make([]byte, 2)
+ binary.BigEndian.PutUint16(crcBytes, crc)
+ frame = append(frame, crcBytes...)
+
+ fmt.Printf("set power %d, cmd %2X\n", val, frame)
+
+ _, err := r.DevPort.Write(frame)
+ if err != nil {
+ return nil
+ }
+
+ // todo parse response
+ r.ReadResponse()
+
+ return err
+}
+
+func (r *Reader) SetBuzzer(enable bool) error {
+ cmd := "5A0001011E000100653D"
+ if !enable {
+ cmd = "5A0001011E000101751C"
+ }
+ data, _ := hex.DecodeString(cmd)
+
+ _, err := r.DevPort.Write(data)
+ if err != nil {
+ return err
+ }
+
+ // todo parse response
+ r.ReadResponse()
+
+ return nil
+}
+
+func parseDeviceInfo(bytes []byte) {
+ // 鍒濆鍖栬В鏋愮殑鍋忕Щ閲�
+ offset := 1
+
+ // 瑙f瀽鍗忚鎺у埗瀛�
+ controlWord := bytes[offset : offset+4]
+ offset += 4
+
+ // 瑙f瀽鏁版嵁闀垮害
+ dataLength := int(bytes[offset])*256 + int(bytes[offset+1])
+ offset += 2
+
+ // 瑙f瀽璇诲啓鍣ㄥ簭鍒楀彿
+ serialNumberLen := int(bytes[offset])*256 + int(bytes[offset+1])
+ offset += 2
+ serialNumber := bytes[offset : offset+serialNumberLen]
+ offset += serialNumberLen
+
+ // 瑙f瀽涓婄數鏃堕棿锛�4瀛楄妭锛�
+ upTimeBytes := bytes[offset : offset+4]
+ offset += 4
+
+ // 瑙f瀽鍩哄甫缂栬瘧鏃堕棿闀垮害锛�2瀛楄妭锛�
+ baseBandTimeLen := int(bytes[offset])*256 + int(bytes[offset+1])
+ offset += 2
+
+ // 瑙f瀽鍩哄甫缂栬瘧鏃堕棿锛堟牴鎹暱搴﹀瓧娈佃В鏋愶級
+ baseBandTime := bytes[offset : offset+baseBandTimeLen]
+ offset += baseBandTimeLen
+
+ // 瑙f瀽搴旂敤杞欢鐗堟湰锛�4瀛楄妭锛�
+ appVer := bytes[offset : offset+4]
+ offset += 4
+
+ // 灏嗗瓧鑺傛暟缁勮浆鎹负鍙瀛楃涓�
+ serialNumberStr := string(serialNumber)
+ baseBandTimeStr := string(baseBandTime)
+ appVerStr := fmt.Sprintf("%d.%d.%d.%d", appVer[0], appVer[1], appVer[2], appVer[3])
+
+ // 瑙f瀽涓婄數鏃堕棿锛堝皢瀛楄妭鏁扮粍杞负鏁存暟锛�
+ upTime := int(upTimeBytes[0])<<24 + int(upTimeBytes[1])<<16 + int(upTimeBytes[2])<<8 + int(upTimeBytes[3])
+
+ // 鎵撳嵃缁撴灉
+ fmt.Printf("鍗忚鎺у埗瀛�: %X\n", controlWord)
+ fmt.Printf("鏁版嵁闀垮害: %d\n", dataLength)
+ fmt.Printf("璇诲啓鍣ㄥ簭鍒楀彿: %s\n", serialNumberStr)
+ fmt.Printf("璇诲啓鍣ㄤ笂鐢垫椂闂�: %d绉抃n", upTime)
+ fmt.Printf("鍩哄甫缂栬瘧鏃堕棿: %s\n", baseBandTimeStr)
+ fmt.Printf("搴旂敤杞欢鐗堟湰: %s\n", appVerStr)
+}
--
Gitblit v1.8.0