From 4ca3791590a7bf50222aa5f80e53edf04739108a Mon Sep 17 00:00:00 2001 From: zhangzengfei <zhangzengfei@smartai.com> Date: 星期二, 22 十月 2024 17:20:23 +0800 Subject: [PATCH] fix 1400 post floor farmat --- rfid/rw.go | 194 +++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 167 insertions(+), 27 deletions(-) diff --git a/rfid/rw.go b/rfid/rw.go index 3761e90..4cb8d2d 100644 --- a/rfid/rw.go +++ b/rfid/rw.go @@ -13,18 +13,21 @@ 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 EPCData string - ReadTimestamp int64 + ReadTimeout int + Alive bool + HeartbeatTime int64 DevPort *serial.Port } @@ -80,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) { @@ -91,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) @@ -118,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]) @@ -144,7 +150,7 @@ // 鍥炶皟浼犻�乪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 { @@ -162,6 +168,20 @@ 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) @@ -187,10 +207,10 @@ if buf[0] != 0x5A { continue // 蹇界暐閿欒甯� } - fmt.Printf("Read message %x\n", buf[:n]) // 鎵撳嵃鍗忚鎺у埗瀛楄繘琛岃皟璇� + + 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) { @@ -198,25 +218,145 @@ continue } - // 瑙f瀽鍗忚鎺у埗瀛� (浠呭湪闇�瑕佹椂浣跨敤) - //fmt.Printf("Control Word: %x\n", buf[1:5]) // 鎵撳嵃鍗忚鎺у埗瀛楄繘琛岃皟璇� + r.HeartbeatTime = time.Now().Unix() + r.Alive = true + // 瑙f瀽鍗忚鎺у埗瀛� controlWord := binary.BigEndian.Uint32(buf[1:5]) - if controlWord != ControlWordEPCReadResponse6C { - fmt.Printf("Control Word: %d, rec word %d\n", ControlWordEPCReadResponse6C, controlWord) - continue + + 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) } - - // 瑙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) } } } + +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