|
1 package main |
|
2 |
|
3 import ( |
|
4 "io" |
|
5 "fmt" |
|
6 "log" |
|
7 |
|
8 "github.com/tarm/goserial" |
|
9 ) |
|
10 |
|
11 type measurement struct { |
|
12 header int |
|
13 systolic int |
|
14 diastolic int |
|
15 pulse int |
|
16 month int |
|
17 day int |
|
18 hour int |
|
19 minute int |
|
20 year int |
|
21 } |
|
22 |
|
23 func getData(s io.ReadWriteCloser, buf []byte, size int) (int, error) { |
|
24 t := 0 |
|
25 b := buf |
|
26 for t < size { |
|
27 n, err := s.Read(b[t:]) |
|
28 if err != nil { |
|
29 log.Fatal(err) // XXX |
|
30 return t, err |
|
31 } |
|
32 //log.Printf("(%d bytes) %q\n", n, b[t:t+1]) |
|
33 t = t + n |
|
34 } |
|
35 return t, nil |
|
36 } |
|
37 |
|
38 func main() { |
|
39 c := &serial.Config{Name: "/dev/ttyUSB0", Baud: 4800} |
|
40 s, err := serial.OpenPort(c) |
|
41 if err != nil { |
|
42 log.Fatal(err) |
|
43 return |
|
44 } |
|
45 |
|
46 q := []byte("\xaa") |
|
47 //log.Printf("Query: %q\n", q) |
|
48 log.Println("Starting handshake...") |
|
49 n, err := s.Write(q) |
|
50 if err != nil { |
|
51 log.Fatal(err) |
|
52 return |
|
53 } |
|
54 |
|
55 buf := make([]byte, 128) |
|
56 n, err = getData(s, buf, 1) |
|
57 if err != nil { |
|
58 log.Fatal(err) |
|
59 return |
|
60 } |
|
61 if n == 1 && buf[0] == '\x55' { |
|
62 log.Println("Handshake successful.") |
|
63 } else { |
|
64 log.Printf("(%d bytes) %q\n", n, buf[:n]) |
|
65 s.Close() |
|
66 return |
|
67 } |
|
68 |
|
69 // =================== Desc ===================== |
|
70 q = []byte("\xa4") |
|
71 //log.Printf("Query: %q\n", q) |
|
72 log.Println("Requesting device description...") |
|
73 n, err = s.Write(q) |
|
74 if err != nil { |
|
75 log.Fatal(err) |
|
76 return |
|
77 } |
|
78 |
|
79 n, err = getData(s, buf, 32) |
|
80 log.Printf("DESC> %q\n", buf[:n]) |
|
81 |
|
82 // =================== Count ===================== |
|
83 q = []byte("\xa2") |
|
84 //log.Printf("Query: %q\n", q) |
|
85 log.Println("Requesting data counter...") |
|
86 n, err = s.Write(q) |
|
87 if err != nil { |
|
88 log.Fatal(err) |
|
89 return |
|
90 } |
|
91 |
|
92 n, err = getData(s, buf, 1) |
|
93 if err != nil { |
|
94 log.Fatal(err) |
|
95 return |
|
96 } |
|
97 var nRecords int |
|
98 if n == 1 { |
|
99 log.Printf("%d item(s) available.", buf[0]) |
|
100 nRecords = int(buf[0]) |
|
101 } else { |
|
102 log.Printf("(%d bytes) %q\n", n, buf[:n]) |
|
103 return |
|
104 } |
|
105 |
|
106 for i := 0; i < nRecords; i++ { |
|
107 q = []byte{'\xa3', uint8(i + 1)} |
|
108 //log.Printf("Query: %q\n", q) |
|
109 //log.Printf("Requesting measurement %d...", i+1) |
|
110 n, err = s.Write(q) |
|
111 if err != nil { |
|
112 log.Fatal(err) |
|
113 return |
|
114 } |
|
115 |
|
116 n, err = getData(s, buf, 9) |
|
117 //log.Printf("DESC> %q\n", buf[:n]) |
|
118 |
|
119 var data measurement |
|
120 data.header = int(buf[0]) |
|
121 data.systolic = int(buf[1]) + 25 |
|
122 data.diastolic = int(buf[2]) + 25 |
|
123 data.pulse = int(buf[3]) |
|
124 data.month = int(buf[4]) |
|
125 data.day = int(buf[5]) |
|
126 data.hour = int(buf[6]) |
|
127 data.minute = int(buf[7]) |
|
128 data.year = int(buf[8]) + 2000 |
|
129 fmt.Printf("%d;%x;%d-%02d-%02d %02d:%02d;%d;%d;%d\n", |
|
130 i+1, data.header, |
|
131 data.year, data.month, data.day, |
|
132 data.hour, data.minute, |
|
133 data.systolic, data.diastolic, data.pulse) |
|
134 } |
|
135 |
|
136 s.Close() |
|
137 } |