4 from serial import Serial
5 from datetime import datetime
8 class State: #information stored
17 self.time = datetime.utcnow()
64 snsMap = {SNS_ACC: 'acc',
70 cmdMap = {CMD_START, 'start',
74 sizeMap = {TYP_S8: 1, TYP_S16: 2, TYP_S32: 4,
75 TYP_U8: 1, TYP_U16: 2, TYP_U32: 4,
76 TYP_F32: 4, TYP_F64: 8}
78 fmtMap = {TYP_S8: 'b', TYP_S16: 'h', TYP_S32: 'i',
79 TYP_U8: 'B', TYP_U16: 'H', TYP_U32: 'I',
80 TYP_F32: 'f', TYP_F64: 'd'}
83 index = 0 # read index
84 count = 0 # number of items in frame
85 length = 0 # length of frame (in bytes)
86 bits_sns = 0 # sensor type
87 bits_typ = 0 # data type
88 binary = "" # binary read-in
89 values = [] # converted numeric data
90 total = 0 # total states read so far
98 def findCode(dataMap, name):
100 if dataMap[code] == name:
102 print("[ERROR] No code found")
105 def parse(self, byte):
106 # save current pos and increment read index
107 # if we have an error we cna reset index below
111 if pos == Frame.HEADER_POS:
112 if ord(byte) != Frame.HEADER:
114 #print('parse: header %02x' % ord(byte))
116 elif pos == Frame.BITS_POS:
117 self.bits_sns = (ord(byte) & Frame.SNS_MASK) >> Frame.SNS_SHIFT
118 self.bits_typ = (ord(byte) & Frame.TYP_MASK) >> Frame.TYP_SHIFT
119 if self.bits_sns >= Frame.SNS_NUM:
121 if self.bits_typ >= Frame.TYP_NUM:
123 #print('parse: bits sns=%d typ=%d' %
124 # (self.bits_sns, self.bits_typ))
126 elif pos == Frame.COUNT_POS:
127 wordsize = Frame.sizeMap[self.bits_typ]
128 self.count = ord(byte)
129 self.length = Frame.DATA_POS + self.count*wordsize + 1
130 #print('parse: count cnt=%d len=%d' %
131 # (self.count, self.length))
133 elif pos < self.length-1:
135 #print('parse: data %02x @%d' %
136 # (ord(byte), pos-Frame.DATA_POS))
138 elif pos == self.length-1:
139 #print('parse: tail %02x' % ord(byte))
140 if ord(byte) == Frame.TAIL:
141 state = self.convert()
148 elif pos > self.length-1:
149 print('Error parsing')
151 # Convert frame to state
154 fmt = Frame.fmtMap[self.bits_typ] * self.count
155 sns = Frame.snsMap[self.bits_sns]
156 self.values = unpack('<'+fmt, self.binary)
157 #print('convert: %3s = \'%3s\'%%[%s] -> [%s]' %
158 # (sns, fmt, hexDump(self.binary), fltDump(self.values)))
160 if self.total % 100 == 0:
161 print('read %d samples' % self.total);
166 setattr(state, sns, self.values)
171 def __init__(self, config):
172 print('Defice.__init__')
179 print('Device.connect')
183 self.serial = Serial(self.config.device, \
184 baudrate = self.config.baudrate, \
185 parity = self.config.parity, \
186 bytesize = self.config.databits, \
187 stopbits = self.config.stopbits, \
189 for sns in self.config.rate:
190 self.set_rate(sns, self.config.rate[sns])
191 for sns in self.config.enable:
192 self.set_enable(sns, self.config.enable[sns])
193 self.serial.flushInput()
194 except Exception as ex:
197 def disconnect(self):
198 print('Device.disconnect')
199 if self.serial and self.serial.isOpen():
202 def running(self): # isRunning
203 if self.serial == None:
205 if self.serial.isOpen() == False:
209 def set_rate(self, sensor, interval):
210 sns = Frame.findCode(Frame.snsMap, sensor)
211 bits = (sns << Frame.SNS_SHIFT) | \
212 (Frame.CMD_RATE << Frame.CMD_SHIFT)
213 self._write_binary('Bf', bits, interval)
215 def set_enable(self, sensor, enabled):
216 sns = Frame.findCode(Frame.snsMap, sensor)
217 cmd = Frame.CMD_START if enabled else Frame.CMD_STOP
218 bits = (sns << Frame.SNS_SHIFT) | \
219 (cmd << Frame.CMD_SHIFT)
220 self._write_binary('B', bits)
223 if not self.running():
227 while self.serial.inWaiting():
228 byte = self.serial.read()
229 state = self.frame.parse(byte)
236 def frame_len(self, frame):
239 dataType_snsType = ord(frame[1])
240 dataNum = ord(frame[2])
241 dataType = (dataType_snsType & Frame.TYP_MASK) >> Frame.TYP_SHIFT
242 snsType = (dataType_snsType & Frame.SNS_MASK) >> Frame.SNS_SHIFT
243 dataSize = Frame.sizeMap[dataType]
244 return (dataSize*dataNum+4)
246 def printHex(self, frame):
247 frameLen = self.frame_len(frame)
250 print(hex(ord(frame[i])))
254 def _write_binary(self, fmt, *args):
255 #print('Device._write_binary')
257 fmt = 'B' + fmt + 'B'
258 args = [Frame.HEADER] + list(args) + [Frame.TAIL]
259 frame = pack('<'+fmt, *args)
260 print('write: bin:[' + hexDump(frame) + ']')
261 self.serial.write(frame)
266 digits = ['%02x' % ord(byte) for byte in frame]
267 return ' '.join(digits)
270 digits = ['%5.2f' % flt for flt in data]
271 return ' '.join(digits)