Mercurial > code > home > repos > homeauto
comparison service/arduinoNode/arduinoNode.py @ 1034:43a2170bbdb8
refactor to write_arduino_node
Ignore-this: 7b613fe7aa1cef2c88f190db1fcc1c4a
darcs-hash:c3e034630c13dbaf7a73397f82ffc0da68be32fb
author | drewp <drewp@bigasterisk.com> |
---|---|
date | Thu, 28 Jan 2016 00:21:31 -0800 |
parents | 208b960fde31 |
children | 0aa54404df19 |
comparison
equal
deleted
inserted
replaced
1033:bf03f5185e8f | 1034:43a2170bbdb8 |
---|---|
12 from rdflib.parser import StringInputSource | 12 from rdflib.parser import StringInputSource |
13 from twisted.internet import reactor, task | 13 from twisted.internet import reactor, task |
14 from docopt import docopt | 14 from docopt import docopt |
15 | 15 |
16 import devices | 16 import devices |
17 import write_arduino_code | |
17 import dotrender | 18 import dotrender |
18 import rdflib_patch | 19 import rdflib_patch |
19 rdflib_patch.fixQnameOfUriWithTrailingSlash() | 20 rdflib_patch.fixQnameOfUriWithTrailingSlash() |
20 | 21 |
21 logging.basicConfig(level=logging.DEBUG) | 22 logging.basicConfig(level=logging.DEBUG) |
170 log.info("Board %s doesn't care about these statements:", self.uri) | 171 log.info("Board %s doesn't care about these statements:", self.uri) |
171 for s in unused: | 172 for s in unused: |
172 log.info("%r", s) | 173 log.info("%r", s) |
173 | 174 |
174 def generateArduinoCode(self): | 175 def generateArduinoCode(self): |
175 generated = { | 176 code = write_arduino_code.writeCode(self.baudrate, self._devs, self._devCommandNum) |
176 'baudrate': self.baudrate, | 177 code = write_arduino_code.indent(code) |
177 'includes': '', | |
178 'global': '', | |
179 'setups': '', | |
180 'polls': '', | |
181 'idles': '', | |
182 'actions': '', | |
183 } | |
184 for attr in ['includes', 'global', 'setups', 'polls', 'idles', | |
185 'actions']: | |
186 for dev in self._devs: | |
187 if attr == 'includes': | |
188 gen = '\n'.join('#include "%s"\n' % inc | |
189 for inc in dev.generateIncludes()) | |
190 elif attr == 'global': gen = dev.generateGlobalCode() | |
191 elif attr == 'setups': gen = dev.generateSetupCode() | |
192 elif attr == 'polls': gen = dev.generatePollCode() | |
193 elif attr == 'idles': gen = dev.generateIdleCode() | |
194 elif attr == 'actions': | |
195 code = dev.generateActionCode() | |
196 if code: | |
197 gen = '''else if (cmd == %(cmdNum)s) { | |
198 %(code)s | |
199 Serial.write('k'); | |
200 } | |
201 ''' % dict(cmdNum=self._devCommandNum[dev.uri], | |
202 code=code) | |
203 else: | |
204 gen = '' | |
205 else: | |
206 raise NotImplementedError | |
207 | |
208 if gen: | |
209 generated[attr] += '// for %s\n%s\n' % (dev.uri, gen.strip()) | |
210 | |
211 code = ''' | |
212 %(includes)s | |
213 | |
214 %(global)s | |
215 byte frame=0; | |
216 unsigned long lastFrame=0; | |
217 | |
218 void setup() { | |
219 Serial.begin(%(baudrate)d); | |
220 Serial.flush(); | |
221 %(setups)s | |
222 } | |
223 | |
224 void idle() { | |
225 // this slowdown is to spend somewhat less time PWMing, to reduce | |
226 // leaking from on channels to off ones (my shift register has no | |
227 // latching) | |
228 if (micros() < lastFrame + 80) { | |
229 return; | |
230 } | |
231 lastFrame = micros(); | |
232 frame++; | |
233 %(idles)s | |
234 } | |
235 | |
236 void loop() { | |
237 byte head, cmd; | |
238 idle(); | |
239 if (Serial.available() >= 2) { | |
240 head = Serial.read(); | |
241 if (head != 0x60) { | |
242 Serial.flush(); | |
243 return; | |
244 } | |
245 cmd = Serial.read(); | |
246 if (cmd == 0x00) { // poll | |
247 %(polls)s | |
248 Serial.write('x'); | |
249 } else if (cmd == 0x01) { // get code checksum | |
250 Serial.write("CODE_CHECKSUM"); | |
251 } | |
252 %(actions)s | |
253 } | |
254 } | |
255 ''' % generated | |
256 try: | |
257 with tempfile.SpooledTemporaryFile() as codeFile: | |
258 codeFile.write(code) | |
259 codeFile.seek(0) | |
260 code = subprocess.check_output([ | |
261 'indent', | |
262 '-linux', | |
263 '-fc1', # ok to indent comments | |
264 '-i4', # 4-space indent | |
265 '-sob' # swallow blanks (not working) | |
266 ], stdin=codeFile) | |
267 except OSError as e: | |
268 log.warn("indent failed (%r)", e) | |
269 cksum = hashlib.sha1(code).hexdigest() | 178 cksum = hashlib.sha1(code).hexdigest() |
270 code = code.replace('CODE_CHECKSUM', cksum) | 179 code = code.replace('CODE_CHECKSUM', cksum) |
271 return code, cksum | 180 return code, cksum |
272 | 181 |
273 def _readBoardChecksum(self, length): | 182 def _readBoardChecksum(self, length): |
311 finally: | 220 finally: |
312 self.open() | 221 self.open() |
313 | 222 |
314 def _arduinoMake(self, workDir, code): | 223 def _arduinoMake(self, workDir, code): |
315 with open(workDir + '/makefile', 'w') as makefile: | 224 with open(workDir + '/makefile', 'w') as makefile: |
316 makefile.write(''' | 225 makefile.write(write_arduino_code.writeMakefile( |
317 BOARD_TAG = %(tag)s | 226 dev=self.dev, |
318 USER_LIB_PATH := %(libs)s | 227 tag=self.graph.value(self.uri, ROOM['boardTag']), |
319 ARDUINO_LIBS = %(arduinoLibs)s | 228 allLibs=sum((d.generateArduinoLibs() for d in self._devs), []))) |
320 MONITOR_PORT = %(dev)s | |
321 | |
322 include /usr/share/arduino/Arduino.mk | |
323 ''' % { | |
324 'dev': self.dev, | |
325 'tag': self.graph.value(self.uri, ROOM['boardTag']), | |
326 'libs': os.path.abspath('arduino-libraries'), | |
327 'arduinoLibs': ' '.join(sum((d.generateArduinoLibs() | |
328 for d in self._devs), [])), | |
329 }) | |
330 | 229 |
331 with open(workDir + '/main.ino', 'w') as main: | 230 with open(workDir + '/main.ino', 'w') as main: |
332 main.write(code) | 231 main.write(code) |
333 | 232 |
334 subprocess.check_call(['make', 'upload'], cwd=workDir) | 233 subprocess.check_call(['make', 'upload'], cwd=workDir) |