123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- package main
- import (
- "encoding/binary"
- "encoding/hex"
- "fmt"
- "log"
- "os"
- "strconv"
- "strings"
- "time"
- "github.com/chzyer/readline"
- "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
- var sampFreq int
- 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
- }
- defer device.Close()
- if report, err := device.HIDReport(); err != nil {
- log.Println("HID report error:", err)
- return
- } 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[0x23:0x25])
- humidity := binary.BigEndian.Uint16(buf[0x25:0x27])
- ts := uint32(time.Now().Unix())
- log.Printf("%d: %d, %d\n", ts, temp, humidity)
- ReportTelemty(ts, 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
- }
- }
- }
- }()
- var completer = readline.NewPrefixCompleter(
- readline.PcItem("output"),
- readline.PcItem("set-feature"),
- readline.PcItem("get-feature"),
- )
- rl, err := readline.NewEx(&readline.Config{
- Prompt: "> ",
- AutoComplete: completer,
- })
- if err != nil {
- panic(err)
- }
- defer rl.Close()
- log.SetOutput(rl.Stderr())
- //sendcmd(device, "read")
- cmds := []string{
- "read",
- "config",
- "config2",
- "query",
- "dump",
- }
- timeout := 0
- //for _, k := range cmds {
- for k := cmds[0]; ; {
- sendcmd(device, k)
- tmrCmdTimeout.Stop()
- tmrCmdTimeout.Reset(3 * time.Second)
- select {
- case msg := <-chnMain:
- log.Println("Send command [", k, "<>", msg, "] done!")
- tmrCmdTimeout.Stop()
- time.Sleep(time.Duration(sampFreq) * time.Second)
- case <-tmrCmdTimeout.C:
- log.Println("Send command [", k, "] timeout!")
- timeout = 1
- }
- if timeout != 0 {
- break
- }
- }
- 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!")
- }
- 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])
- fmt.Printf(" %s <id> [dd] open USB HID device shell for the given input report size and each [dd] second sample and report once \n", os.Args[0])
- fmt.Printf(" %s -h|--help show this help\n", os.Args[0])
- fmt.Println()
- return
- }
- // Without arguments - enumerate all HID devices
- if len(os.Args) == 1 {
- found := false
- hid.UsbWalk(func(device hid.Device) {
- info := device.Info()
- fmt.Printf("%04x:%04x:%04x:%02x\n", info.Vendor, info.Product, info.Revision, info.Interface)
- found = true
- })
- if !found {
- fmt.Println("No USB HID devices found\n")
- }
- return
- }
- sampFreq = 30
- if len(os.Args) >= 3 {
- duration, err := strconv.Atoi(os.Args[2])
- if err == nil {
- sampFreq = duration
- fmt.Println("Sample duration:", sampFreq)
- }
- }
- hid.UsbWalk(func(device hid.Device) {
- info := device.Info()
- id := fmt.Sprintf("%04x:%04x:%04x:%02x", info.Vendor, info.Product, info.Revision, info.Interface)
- if id != os.Args[1] {
- return
- }
- StartMqttServer()
- shell(device)
- StopMqttServer()
- })
- }
|