]> Pileus Git - ~andy/csm213a-hw/blob - vis/device.py
Work on writing settings to devices
[~andy/csm213a-hw] / vis / device.py
1 import time
2
3 from re       import compile
4 from serial   import Serial
5 from datetime import datetime
6
7 class State:
8         acc   = [None]*3
9         mag   = [None]*3
10         touch = [None]*2
11         light = [None]*1
12         a2d   = [None]*6
13         time  = None
14
15         def __init__(self):
16                 self.time = datetime.utcnow()
17
18 class Device:
19         # Attributes
20         port = "/dev/ttyACM0"
21
22         # Constructors
23         def __init__(self, config):
24                 self.config = config
25                 self.serial = None
26
27         # Methods
28         def connect(self):
29                 try:
30                         self.inbuf  = []
31                         self.serial = Serial(self.port,          \
32                                 baudrate = self.config.baudrate, \
33                                 parity   = self.config.parity,   \
34                                 bytesize = self.config.databits, \
35                                 stopbits = self.config.stopbits, \
36                                 timeout  = 0)
37                         self.control()
38                         self.serial.flushInput()
39                 except Exception as ex:
40                         return str(ex)
41
42         def disconnect(self):
43                 if self.serial and self.serial.isOpen():
44                         self.serial.close()
45
46         def running(self):
47                 if self.serial == None:
48                         return False
49                 if self.serial.isOpen() == False:
50                         return False
51                 return True
52
53         def control(self):
54                 for key in list(self.config.enable.keys()):
55                         state = self.config.enable[key]
56                         rate  = self.config.rate[key]
57                         cmd   = 'start' if state else 'stop'
58                         self._write_ascii('%s %s' % (cmd, key))
59                         self._write_ascii('set %s int %d' % (key, rate))
60
61         def process(self):
62                 items = []
63                 count = 0
64                 limit = 1000
65                 if not self.running():
66                         return items
67                 while self.serial.readable():
68                         try:
69                                 char = self.serial.read().decode()
70                         except Exception as ex:
71                                 char = ''
72                         if len(char) == 0:
73                                 break
74                         if char == '\r' or char == '\n':
75                                 if len(self.inbuf) == 0:
76                                         continue
77                                 line = "".join(self.inbuf)
78                                 print('read: [' + line + ']')
79                                 item = self._parse_ascii(line)
80                                 items.append(item)
81                                 self.inbuf = []
82                         else:
83                                 self.inbuf.append(char)
84                         if count > limit:
85                                 print("Error: exceeded read limit")
86                                 break
87                         count += 1
88                 return items
89
90         # Private methods
91         def _write_ascii(self, line):
92                 if self.serial:
93                         print('write: [' + line + ']')
94                         data = bytes(line+'\n', 'UTF-8')
95                         self.serial.write(data)
96                         self.serial.flush()
97                         time.sleep(0.1)
98
99         def _parse_ascii(self, line):
100                 acc_re = compile("\[ACC\] accX=(.*) accY=(.*) accZ=(.*)")
101                 mag_re = compile("\[MAG\] magX=(.*) magY=(.*) magZ=(.*)")
102                 lgt_re = compile("\[LGT\] Light Intensity=(.*)")
103                 tch_re = compile("\[TCH\] Force=(.*) Distance=(.*)")
104                 a2d_re = compile("\[A2D\] ...")
105
106                 acc_m = acc_re.match(line)
107                 mag_m = mag_re.match(line)
108                 lgt_m = lgt_re.match(line)
109                 tch_m = tch_re.match(line)
110                 a2d_m = a2d_re.match(line)
111
112                 state = State()
113                 if acc_m:
114                         state.acc[0]   = float(acc_m.group(1))
115                         state.acc[1]   = float(acc_m.group(2))
116                         state.acc[2]   = float(acc_m.group(3))
117                 if mag_m:              
118                         state.mag[0]   = float(mag_m.group(1))
119                         state.mag[1]   = float(mag_m.group(2))
120                         state.mag[2]   = float(mag_m.group(3))
121                 if lgt_m:
122                         state.light[0] = float(lgt_m.group(1))
123                 if tch_m:
124                         state.touch[0] = float(tch_m.group(1))
125                 if a2d_m:
126                         state.a2d[0]   = float(tch_m.group(1))
127                         state.a2d[1]   = float(tch_m.group(2))
128                         state.a2d[2]   = float(tch_m.group(3))
129                         state.a2d[3]   = float(tch_m.group(4))
130                         state.a2d[4]   = float(tch_m.group(5))
131                         state.a2d[5]   = float(tch_m.group(6))
132
133                 return state