Prechádzať zdrojové kódy

Add hid read COS temprature meter functions
(Read, clean, query, dump,config, config2)

pacom 3 rokov pred
rodič
commit
251f99df60
6 zmenil súbory, kde vykonal 408 pridanie a 49 odobranie
  1. 66 2
      README.md
  2. 61 0
      example/crc.go
  3. 10 0
      example/go.mod
  4. 16 0
      example/go.sum
  5. 134 47
      example/main.go
  6. 121 0
      example/mqtt.go

+ 66 - 2
README.md

@@ -3,6 +3,70 @@
 COS company temperature/humididy meter read by HID
 
 # hid
-Simple HID driver for Go (pure golang, no dependencies, no cgo)
+ sudo cat /sys/kernel/debug/usb/devices
+T:  Bus=01 Lev=02 Prnt=21 Port=03 Cnt=01 Dev#= 29 Spd=12   MxCh= 0
+D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
+P:  Vendor=0483 ProdID=0003 Rev= 2.00
+S:  Manufacturer=STMicroelectronics
+S:  Product=COS-03 - Device
+S:  SerialNumber=2468ACF08765
+C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr=100mA
+I:* If#= 0 Alt= 0 #EPs= 2 Cls=03(HID  ) Sub=00 Prot=00 Driver=usbhid
+E:  Ad=81(I) Atr=03(Int.) MxPS=  64 Ivl=2ms
+E:  Ad=01(O) Atr=03(Int.) MxPS=  64 Ivl=2ms
 
-Currently only Linux (386/amd64) is supported.
+num : number of data group
+timestamp : MSB, 61509EE4=1632673508="2021-09-27 00:25:08"-8Hour = "2021-09-26 16:25:08" global timestamp + 8hour
+temp : temperature MSB, 00F9 = 248= 24.8 deg.
+humid: Humididy MSB, 02AA=682 = 68.2%
+..........................|num|.timestamp..|.temp|.humid|.timestamp..|.temp| humid|.timestamp..|.temp| humid|                                             
+ 161    IN     00 aa 3a 03  07 61 50 9e  e4 00 f9 02  aa 61 50 9f  20 00 fa 02  aa 61 50 9f  5c 00 fa 02  aa 61 50 9f  ..:..aP......aP. ....aP.\....aP.        11.1.0        
+               98 00 fa 02  ab 61 50 9f  d4 00 f9 02  ab 61 50 a0  10 00 f9 02  aa 61 50 a0  4c 00 f8 02  ac 00 00 2e  .....aP......aP......aP.L.......        11.1.32       
+               e6   
+
+
+161    OUT     00 55 03 01  (2d 2d)(RANDOM INDEX) 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  .U..--..........................         1.1.0        
+               00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 d6  ................................         1.1.32       
+               b7                                                                                                      .                                        1.1.64       
+ 161    IN     00 aa 26 01  ad 9f 00 00  00 00 02 03  01 00 61 50  a6 d0 01 61  50 9d 3e 61  50 9e e4 62  3e a8 58 00  ..&...........aP...aP.>aP..b>.X.         2.1.0        
+               00 00 00 00  00 f6 02 b2  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 3a  ...............................:         2.1.32       
+               c5                                                                                                      .                                        2.1.64       
+ 161    OUT    00 55 01 07  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  .U..............................         3.1.0        
+               00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 c8  ................................         3.1.32       
+               8a                                                                                                      .                                        3.1.64       
+ 161    IN     00 aa 3b 07  55 53 42 2d  54 48 00 00  00 55 53 42  e6 b8 a9 e6  b9 bf e5 ba  a6 e8 ae b0  e5 bd 95 e4  ..;.USB-TH...USB................         4.1.0        
+               bb aa 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 34  ...............................4         4.1.32       
+               dc                                                                                                      .                                        4.1.64       
+ 161    OUT    00 55 01 09  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  .U..............................         5.1.0        
+               00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 c5  ................................         5.1.32       
+               a2                                                                                                      .                                        5.1.64       
+ 161    IN     00 aa 23 09  00 3c 00 3c  03 e8 fe 70  03 e8 00 00  00 00 00 00  00 00 0a 00  ef 7f 00 00  00 00 00 00  ..#..<.<...p....................         6.1.0        
+               00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 ce  ................................         6.1.32       
+               c9                                                                                                      .                                        6.1.64       
+ 161    OUT    00 55 01 02  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  .U..............................         7.1.0        
+               00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 cd  ................................         7.1.32       
+               46                                                                                                      F                                        7.1.64       
+ 161    IN     00 aa 3b 02  00 00 00 22(TOTAL)  55 53 42 2d  54 48 00 00  00 55 53 42  e6 b8 a9 e6  b9 bf e5 ba  a6 e8 ae b0  ..;...."USB-TH...USB............         8.1.0        
+               e5 bd 95 e4  bb aa 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 15  ................................         8.1.32       
+               89                                                                                                      .                                        8.1.64       
+ 161    OUT    00 55 01 0b  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  .U..............................         9.1.0        
+               00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 c7  ................................         9.1.32       
+               da                                                                                                      .                                        9.1.64       
+ 161    IN     00 aa 3b 02  00 00 00 22(TOTAL)  55 53 42 2d  54 48 00 00  00 55 53 42  e6 b8 a9 e6  b9 bf e5 ba  a6 e8 ae b0  ..;...."USB-TH...USB............        10.1.0        
+               e5 bd 95 e4  bb aa 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 15  ................................        10.1.32       
+               89                                                                                                      .                                       10.1.64       
+ 161    IN     00 aa 3a 03  07 61 50 9e  e4 00 f9 02  aa 61 50 9f  20 00 fa 02  aa 61 50 9f  5c 00 fa 02  aa 61 50 9f  ..:..aP......aP. ....aP.\....aP.        11.1.0        
+               98 00 fa 02  ab 61 50 9f  d4 00 f9 02  ab 61 50 a0  10 00 f9 02  aa 61 50 a0  4c 00 f8 02  ac 00 00 2e  .....aP......aP......aP.L.......        11.1.32       
+               e6                                                                                                      .                                       11.1.64       
+ 161    IN     00 aa 3a 03  07 61 50 a0  88 00 fa 02  ab 61 50 a0  c4 00 fa 02  aa 61 50 a1  00 00 fa 02  aa 61 50 a1  ..:..aP......aP......aP......aP.        12.1.0        
+               3c 00 fa 02  aa 61 50 a1  78 00 fa 02  aa 61 50 a1  b4 00 fa 02  a9 61 50 a1  f0 00 fa 02  a8 00 00 f7  <....aP.x....aP......aP.........        12.1.32       
+               6c                                                                                                      l                                       12.1.64       
+ 161    IN     00 aa 3a 03  07 61 50 a2  2c 00 fa 02  aa 61 50 a2  68 00 f9 02  aa 61 50 a2  a4 00 fa 02  aa 61 50 a2  ..:..aP.,....aP.h....aP......aP.        13.1.0        
+               e0 00 f9 02  aa 61 50 a3  1c 00 fa 02  aa 61 50 a3  58 00 fa 02  aa 61 50 a3  94 00 fa 02  aa 00 00 fc  .....aP......aP.X....aP.........        13.1.32       
+               7d                                                                                                      .                                       13.1.64       
+ 161    IN     00 aa 3a 03  07 61 50 a3  d0 00 f9 02  aa 61 50 a4  0c 00 fa 02  ab 61 50 a4  48 00 f9 02  ab 61 50 a4  ..:..aP......aP......aP.H....aP.        14.1.0        
+               84 00 f8 02  aa 61 50 a4  c0 00 f8 02  aa 61 50 a4  fc 00 f8 02  ac 61 50 a5  38 00 f8 02  ac 00 00 24  .....aP......aP......aP.8......$        14.1.32       
+               5c                                                                                                      \                                       14.1.64       
+ 161    IN     00 aa 3a 03  06 61 50 a5  74 00 f7 02  ad 61 50 a5  b0 00 f7 02  af 61 50 a5  ec 00 f7 02  af 61 50 a6  ..:..aP.t....aP......aP......aP.        15.1.0        
+               28 00 f7 02  ae 61 50 a6  64 00 f7 02  af 61 50 a6  a0 00 f6 02  af 00 00 00  00 00 00 00  00 00 00 98  (....aP.d....aP.................        15.1.32       
+               f1     

+ 61 - 0
example/crc.go

@@ -0,0 +1,61 @@
+package main
+
+import "fmt"
+
+var MbTable = []uint16{
+	0X0000, 0XC0C1, 0XC181, 0X0140, 0XC301, 0X03C0, 0X0280, 0XC241,
+	0XC601, 0X06C0, 0X0780, 0XC741, 0X0500, 0XC5C1, 0XC481, 0X0440,
+	0XCC01, 0X0CC0, 0X0D80, 0XCD41, 0X0F00, 0XCFC1, 0XCE81, 0X0E40,
+	0X0A00, 0XCAC1, 0XCB81, 0X0B40, 0XC901, 0X09C0, 0X0880, 0XC841,
+	0XD801, 0X18C0, 0X1980, 0XD941, 0X1B00, 0XDBC1, 0XDA81, 0X1A40,
+	0X1E00, 0XDEC1, 0XDF81, 0X1F40, 0XDD01, 0X1DC0, 0X1C80, 0XDC41,
+	0X1400, 0XD4C1, 0XD581, 0X1540, 0XD701, 0X17C0, 0X1680, 0XD641,
+	0XD201, 0X12C0, 0X1380, 0XD341, 0X1100, 0XD1C1, 0XD081, 0X1040,
+	0XF001, 0X30C0, 0X3180, 0XF141, 0X3300, 0XF3C1, 0XF281, 0X3240,
+	0X3600, 0XF6C1, 0XF781, 0X3740, 0XF501, 0X35C0, 0X3480, 0XF441,
+	0X3C00, 0XFCC1, 0XFD81, 0X3D40, 0XFF01, 0X3FC0, 0X3E80, 0XFE41,
+	0XFA01, 0X3AC0, 0X3B80, 0XFB41, 0X3900, 0XF9C1, 0XF881, 0X3840,
+	0X2800, 0XE8C1, 0XE981, 0X2940, 0XEB01, 0X2BC0, 0X2A80, 0XEA41,
+	0XEE01, 0X2EC0, 0X2F80, 0XEF41, 0X2D00, 0XEDC1, 0XEC81, 0X2C40,
+	0XE401, 0X24C0, 0X2580, 0XE541, 0X2700, 0XE7C1, 0XE681, 0X2640,
+	0X2200, 0XE2C1, 0XE381, 0X2340, 0XE101, 0X21C0, 0X2080, 0XE041,
+	0XA001, 0X60C0, 0X6180, 0XA141, 0X6300, 0XA3C1, 0XA281, 0X6240,
+	0X6600, 0XA6C1, 0XA781, 0X6740, 0XA501, 0X65C0, 0X6480, 0XA441,
+	0X6C00, 0XACC1, 0XAD81, 0X6D40, 0XAF01, 0X6FC0, 0X6E80, 0XAE41,
+	0XAA01, 0X6AC0, 0X6B80, 0XAB41, 0X6900, 0XA9C1, 0XA881, 0X6840,
+	0X7800, 0XB8C1, 0XB981, 0X7940, 0XBB01, 0X7BC0, 0X7A80, 0XBA41,
+	0XBE01, 0X7EC0, 0X7F80, 0XBF41, 0X7D00, 0XBDC1, 0XBC81, 0X7C40,
+	0XB401, 0X74C0, 0X7580, 0XB541, 0X7700, 0XB7C1, 0XB681, 0X7640,
+	0X7200, 0XB2C1, 0XB381, 0X7340, 0XB101, 0X71C0, 0X7080, 0XB041,
+	0X5000, 0X90C1, 0X9181, 0X5140, 0X9301, 0X53C0, 0X5280, 0X9241,
+	0X9601, 0X56C0, 0X5780, 0X9741, 0X5500, 0X95C1, 0X9481, 0X5440,
+	0X9C01, 0X5CC0, 0X5D80, 0X9D41, 0X5F00, 0X9FC1, 0X9E81, 0X5E40,
+	0X5A00, 0X9AC1, 0X9B81, 0X5B40, 0X9901, 0X59C0, 0X5880, 0X9841,
+	0X8801, 0X48C0, 0X4980, 0X8941, 0X4B00, 0X8BC1, 0X8A81, 0X4A40,
+	0X4E00, 0X8EC1, 0X8F81, 0X4F40, 0X8D01, 0X4DC0, 0X4C80, 0X8C41,
+	0X4400, 0X84C1, 0X8581, 0X4540, 0X8701, 0X47C0, 0X4680, 0X8641,
+	0X8201, 0X42C0, 0X4380, 0X8341, 0X4100, 0X81C1, 0X8081, 0X4040}
+
+func CheckSum(data []byte) uint16 {
+	var crc16 uint16
+	crc16 = 0xffff
+	for _, v := range data {
+		n := uint8(uint16(v) ^ crc16)
+		crc16 >>= 8
+		crc16 ^= MbTable[n]
+	}
+	return crc16
+}
+
+func FmtPrintBinary(buf []byte) {
+	if buf != nil && len(buf) != 0 {
+		sv := ""
+		for index, v := range buf {
+			sv += fmt.Sprintf("0x%02X,", v)
+			if index%16 == 15 {
+				sv += "\n"
+			}
+		}
+		fmt.Println(sv)
+	}
+}

+ 10 - 0
example/go.mod

@@ -0,0 +1,10 @@
+module github.com/hid/example
+
+go 1.14
+
+require (
+	github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e
+	github.com/eclipse/paho.mqtt.golang v1.3.5
+	github.com/yuguorong/go v0.0.0-20180604090527-bdc77568d726
+	github.com/zserge/hid v0.0.0-20190124175232-e1626f1782f3
+)

+ 16 - 0
example/go.sum

@@ -0,0 +1,16 @@
+github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=
+github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
+github.com/eclipse/paho.mqtt.golang v1.3.5 h1:sWtmgNxYM9P2sP+xEItMozsR3w0cqZFlqnNN1bdl41Y=
+github.com/eclipse/paho.mqtt.golang v1.3.5/go.mod h1:eTzb4gxwwyWpqBUHGQZ4ABAV7+Jgm1PklsYT/eo8Hcc=
+github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
+github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/yuguorong/go v0.0.0-20180604090527-bdc77568d726 h1:3BSFfDVmj5yqpvj3H9m1EpZWhEKgJXW2C4MbTRv6rIM=
+github.com/yuguorong/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:i+SDEIi6IWgErb4Yq6H542yr5F8vxSoNbe9wFC+N5jc=
+github.com/zserge/hid v0.0.0-20190124175232-e1626f1782f3 h1:DAdExZJtAXR150WHt4wzTCzHH7lXkD4vKN9xLtF05VU=
+github.com/zserge/hid v0.0.0-20190124175232-e1626f1782f3/go.mod h1:OpyudhSlA/GSwcydk4+0Ex9DBI+9mOs/Pk06vmIjLSA=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 h1:Jcxah/M+oLZ/R4/z5RzfPzGbPXnVDPkEDtf2JnuxN+U=
+golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

+ 134 - 47
example/main.go

@@ -1,6 +1,7 @@
 package main
 
 import (
+	"encoding/binary"
 	"encoding/hex"
 	"fmt"
 	"log"
@@ -12,7 +13,51 @@ import (
 	"github.com/zserge/hid"
 )
 
+//output: 550301000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037c3
+//input : 550301000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037c3
+var cur_cmd string
+var cmdList map[string][]byte
+var tmrCmdTimeout *time.Timer = nil
+var chnMain chan string
+
+func init() {
+	cmdList = map[string][]byte{
+		"read":    []byte{0x55, 0x03, 0x01, 0x00},
+		"config":  []byte{0x55, 0x01, 0x07, 0x00},
+		"config2": []byte{0x55, 0x01, 0x09, 0x00},
+		"query":   []byte{0x55, 0x01, 0x02, 0x00}, //QUERY NAME
+		"dump":    []byte{0x55, 0x01, 0x0b, 0x00},
+		"clean":   []byte{0x55, 0x01, 0x05, 0x00},
+	}
+}
+
+func sendcmd(device hid.Device, strcmd string) error {
+	log.Println("send cmd : ", strcmd)
+	cmd := cmdList[strcmd]
+	cmdbuf := make([]byte, 64)
+	copy(cmdbuf[0:4], cmd[0:4])
+	crc := CheckSum(cmdbuf[0:62])
+	cmdbuf[63] = byte(crc >> 8)
+	cmdbuf[62] = byte(crc)
+	log.Println("output:", hex.EncodeToString(cmdbuf))
+	cur_cmd = strcmd
+	if _, err := device.Write(cmdbuf, 1*time.Second); err != nil {
+		log.Println("Output report write failed:", err)
+		return err
+	}
+
+	return nil
+}
+
+func resetCmdTimer() {
+	if tmrCmdTimeout != nil {
+		tmrCmdTimeout.Stop()
+		tmrCmdTimeout.Reset(3 * time.Second)
+	}
+}
+
 func shell(device hid.Device) {
+
 	if err := device.Open(); err != nil {
 		log.Println("Open error: ", err)
 		return
@@ -25,43 +70,60 @@ func shell(device hid.Device) {
 	} else {
 		log.Println("HID report", hex.EncodeToString(report))
 	}
+	chnMain = make(chan string, 20)
+	tmrCmdTimeout = time.NewTimer(time.Second)
+	defer tmrCmdTimeout.Stop()
+
+	num_total := 0
+	num_read := 0
 
 	go func() {
+
 		for {
 			if buf, err := device.Read(-1, 1*time.Second); err == nil {
 				log.Println("Input report:  ", hex.EncodeToString(buf))
+				resetCmdTimer()
+				switch cur_cmd {
+				case "read":
+					FmtPrintBinary(buf)
+					temp := binary.BigEndian.Uint16(buf[23:25])
+					humidity := binary.BigEndian.Uint16(buf[25:27])
+					log.Printf("%d, %d\n", temp, humidity)
+					chnMain <- cur_cmd
+				case "query": // aa3b020000861c5553422d5448000000555342e6b8a9e6b9bfe5baa6e8aeb0e5bd95e4bbaa000000000000000000000000000000000000000000000000006223
+					num_total = int(buf[6])
+					log.Println(num_total)
+					chnMain <- cur_cmd
+				case "dump":
+					if buf[2] == 2 {
+						num_total = int(buf[6])
+						log.Println(num_total)
+						//                   aa 3a 03 07  6150d959 00f3 02c4;  6150d97700f302c16150d99500f302be6150d9b300f302be6150d9d100f202bd6150d9ef00f302c46150da0d00f202c200001f77
+					} else if buf[2] == 3 { //aa 3a 03 07; 61509ee4 00f9 02aa;  61509f2000fa02aa61509f5c00fa02aa61509f9800fa02ab61509fd400f902ab6150a01000f902aa6150a04c00f802ac00002ee6
+						items := int(buf[3])
+						for i := 0; i < items; i++ {
+							pos := i*8 + 4
+							ts := binary.BigEndian.Uint32(buf[pos:pos+4]) - 8*3600
+							temp := binary.BigEndian.Uint16(buf[pos+4 : pos+6])
+							humidity := binary.BigEndian.Uint16(buf[pos+6 : pos+8])
+							if ts > 1632760878 {
+								ReportTelemty(ts, temp, humidity)
+							}
+							num_read++
+						}
+						if items < 7 {
+							log.Printf("Total recived :%d\n", num_read)
+							chnMain <- cur_cmd
+						}
+					}
+				default:
+					log.Println(cur_cmd + " skipped")
+					chnMain <- cur_cmd
+				}
 			}
 		}
 	}()
 
-	commands := map[string]func([]byte){
-		"output": func(b []byte) {
-			if len(b) == 0 {
-				log.Println("Invalid input: output report data expected")
-			} else if n, err := device.Write(b, 1*time.Second); err != nil {
-				log.Println("Output report write failed:", err)
-			} else {
-				log.Printf("Output report: written %d bytes\n", n)
-			}
-		},
-		"set-feature": func(b []byte) {
-			if len(b) == 0 {
-				log.Println("Invalid input: feature report data expected")
-			} else if err := device.SetReport(0, b); err != nil {
-				log.Println("Feature report write failed:", err)
-			} else {
-				log.Printf("Feature report: " + hex.EncodeToString(b) + "\n")
-			}
-		},
-		"get-feature": func(b []byte) {
-			if b, err := device.GetReport(0); err != nil {
-				log.Println("Feature report read failed:", err)
-			} else {
-				log.Println("Feature report: " + hex.EncodeToString(b) + "\n")
-			}
-		},
-	}
-
 	var completer = readline.NewPrefixCompleter(
 		readline.PcItem("output"),
 		readline.PcItem("set-feature"),
@@ -78,34 +140,57 @@ func shell(device hid.Device) {
 	defer rl.Close()
 	log.SetOutput(rl.Stderr())
 
-out:
-	for {
-		line, err := rl.Readline()
-		if err != nil {
+	//sendcmd(device, "read")
+	cmds := []string{
+		"read",
+		"config",
+		"config2",
+		"query",
+		"dump",
+	}
+
+	timeout := 0
+
+	for _, k := range cmds {
+		sendcmd(device, k)
+		tmrCmdTimeout.Stop()
+		tmrCmdTimeout.Reset(3 * time.Second)
+		select {
+		case msg := <-chnMain:
+			log.Println("Send command [", k, "<>", msg, "] done!")
+		case <-tmrCmdTimeout.C:
+			log.Println("Send command [", k, "] timeout!")
+			timeout = 1
+		}
+		if timeout != 0 {
 			break
 		}
-		line = strings.ToLower(line)
-		for cmd, f := range commands {
-			if strings.HasPrefix(line, cmd) {
-				line = strings.TrimSpace(line[len(cmd):])
-				raw := []byte{}
-				if len(line) > 0 {
-					raw = make([]byte, len(line)/2, len(line)/2)
-					if _, err := hex.Decode(raw, []byte(line)); err != nil {
-						log.Println("Invalid input:", err)
-						log.Println(">>", hex.EncodeToString(raw))
-						continue out
-					}
+	}
+	time.Sleep(1 * time.Second)
+	log.Printf("\nConfirm to clean all record data in device? [Yes/no]:")
+	if timeout == 0 && num_read > 0 && num_read == num_total {
+		line, err := rl.Readline()
+		if err == nil {
+			line = strings.ToLower(line)
+			switch line {
+			case "yes", "y":
+				sendcmd(device, "clean")
+				tmrCmdTimeout.Stop()
+				tmrCmdTimeout.Reset(3 * time.Second)
+				select {
+				case <-chnMain:
+				case <-tmrCmdTimeout.C:
+					log.Println("Send command [clean] timeout!")
 				}
-				f(raw)
-				continue out
+			default:
+				log.Println("Skip clean device")
 			}
 		}
 	}
+
 }
 
 func main() {
-
 	if len(os.Args) == 2 && (os.Args[1] == "-h" || os.Args[1] == "--help") {
 		fmt.Println("USAGE:")
 		fmt.Printf("  %s              list USB HID devices\n", os.Args[0])
@@ -136,6 +221,8 @@ func main() {
 			return
 		}
 
+		StartMqttServer()
 		shell(device)
+		StopMqttServer()
 	})
 }

+ 121 - 0
example/mqtt.go

@@ -0,0 +1,121 @@
+package main
+
+import (
+	"encoding/json"
+	"fmt"
+	"strconv"
+	"strings"
+	"time"
+
+	MQTT "github.com/eclipse/paho.mqtt.golang"
+	"github.com/yuguorong/go/log"
+)
+
+type QdMqtt struct {
+	User     string
+	Pswd     string
+	MqttUrl  string
+	MqttPort string
+	cnn      MQTT.Client
+}
+
+const (
+	mqttBrokerUser = ""
+	mqttBrokerPswd = ""
+)
+
+type CbRegistMqttSubs func(cnn *QdMqtt) int
+
+var cbMqttEdgeConfig MQTT.MessageHandler = func(client MQTT.Client, msg MQTT.Message) {
+	log.Infof("R_TOPIC: %s\n", msg.Topic())
+	log.Infof("R_MSG: %s\n", msg.Payload())
+}
+
+func Mqttsubs(mqtt *QdMqtt, subtopic string, Qos byte, hdlr MQTT.MessageHandler) {
+	fmt.Println("MQTT sub :[" + subtopic + "]")
+	if token := mqtt.cnn.Subscribe(subtopic, Qos, hdlr); token.Wait() && token.Error() != nil {
+		log.Info(token.Error())
+	}
+}
+
+func (mqtt *QdMqtt) PublishObj(topic string, qos byte, in interface{}) {
+	jsonBytes, _ := json.Marshal(in)
+	sjson := string(jsonBytes)
+	log.Info(topic)
+	log.Info(sjson)
+	mqtt.cnn.Publish(topic, qos, true, sjson)
+}
+
+//MqttDisocnnect mqtt disconnect
+func (mqtt *QdMqtt) Disocnnect() {
+	mqtt.cnn.Disconnect(0)
+}
+
+//MqttConnServer mqtt init and connect server
+func (mqtt *QdMqtt) ConnServer(retry int, cbSubs CbRegistMqttSubs) {
+	//create a ClientOptions struct setting the broker address, clientid, turn
+	//off trace output and set the default message handler
+	suid := "8d18db45-2fa6-410a-a46d-acf30f011dac"
+	brokerurl := "tcp://" + strings.Trim(mqtt.MqttUrl, " ") + ":" + strings.Trim(mqtt.MqttPort, "")
+	log.Info("Mqtt broker:", brokerurl)
+	opts := MQTT.NewClientOptions().AddBroker(brokerurl)
+	opts.SetClientID(suid)
+	opts.SetUsername(mqtt.User)
+	opts.SetPassword(mqtt.Pswd)
+	opts.SetDefaultPublishHandler(cbMqttEdgeConfig)
+
+	//create and start a client using the above ClientOptions
+	mqtt.cnn = MQTT.NewClient(opts)
+	for ; retry != 0; retry-- {
+		if token := mqtt.cnn.Connect(); token.Wait() && token.Error() == nil {
+			if cbSubs != nil {
+				cbSubs(mqtt)
+			}
+			log.Info("MQTT connect OK!")
+			return
+		} else {
+			log.Error("Retry to connect the MQTT server!! ", token.Error())
+		}
+		time.Sleep(time.Duration(3) * time.Second)
+	}
+	log.Info("Fault Error! can not connect MQTT server!!!")
+}
+
+func AppMqttSubs(mqtt *QdMqtt) int {
+	Mqttsubs(mqtt, "/sub/default", 1, cbMqttEdgeConfig)
+	return 0
+}
+
+var mqServer *QdMqtt = nil
+
+func MqttConnServer(cbSubs CbRegistMqttSubs) *QdMqtt {
+	mq := &QdMqtt{
+		User:     "5V1K3yCy5I5TRlVoCeeY", //"6XiAxAxtm0uTPnzwjtWd",
+		Pswd:     "",
+		MqttUrl:  "test-sbuilding.pacom.cn",
+		MqttPort: "1885",
+	}
+	mq.ConnServer(-1, cbSubs)
+	return mq
+}
+
+//{"ts":1632289574000, "values":{"temperature":"26.6", "pressure":"1000"}}
+func ReportTelemty(ts uint32, temp uint16, humidity uint16) {
+	devVal := make(map[string]interface{})
+	devVal["ts"] = float64(ts) * 1000
+	devItems := make(map[string]string)
+	devItems["temperature"] = strconv.Itoa(int(temp)/10) + "." + strconv.Itoa(int(temp)%10)
+	devItems["humidity"] = strconv.Itoa(int(humidity)/10) + "." + strconv.Itoa(int(humidity)%10)
+	devVal["values"] = devItems
+	mqServer.PublishObj("v1/devices/me/telemetry", 1, devVal)
+}
+
+func StartMqttServer() {
+	log.Info("Start MQTT server")
+	mqServer = MqttConnServer(AppMqttSubs)
+}
+
+func StopMqttServer() {
+	mqServer.Disocnnect()
+	log.Info("Stop MQTT server")
+}