Mercurial > code > home > repos > homeauto
annotate service/arduinoNode/write_arduino_code.py @ 748:6d84cd3eb277
rename to s/sse//; use new browse link
Ignore-this: 912ae9ed9ffe9270445837f9a7308b5
author | drewp@bigasterisk.com |
---|---|
date | Thu, 13 Feb 2020 10:21:05 -0800 |
parents | 3010238b94a0 |
children |
rev | line source |
---|---|
229 | 1 import tempfile, subprocess, logging, os |
2 log = logging.getLogger('arduino_code') | |
3 | |
4 def writeMakefile(dev, tag, allLibs): | |
5 return ''' | |
6 BOARD_TAG = %(tag)s | |
7 USER_LIB_PATH := %(libs)s | |
8 ARDUINO_LIBS = %(arduinoLibs)s | |
9 MONITOR_PORT = %(dev)s | |
10 | |
11 include /usr/share/arduino/Arduino.mk | |
12 ''' % { | |
13 'dev': dev, | |
14 'tag': tag, | |
15 'libs': os.path.abspath('arduino-libraries'), | |
16 'arduinoLibs': ' '.join(allLibs), | |
17 } | |
18 | |
19 def writeCode(baudrate, devs, devCommandNum): | |
20 generated = { | |
21 'baudrate': baudrate, | |
22 'includes': '', | |
23 'global': '', | |
24 'setups': '', | |
25 'polls': '', | |
26 'idles': '', | |
27 'actions': '', | |
28 } | |
29 for attr in ['includes', 'global', 'setups', 'polls', 'idles', | |
30 'actions']: | |
31 for dev in devs: | |
32 if attr == 'includes': | |
33 gen = '\n'.join('#include "%s"\n' % inc | |
34 for inc in dev.generateIncludes()) | |
35 elif attr == 'global': gen = dev.generateGlobalCode() | |
36 elif attr == 'setups': gen = dev.generateSetupCode() | |
37 elif attr == 'polls': gen = dev.generatePollCode() | |
38 elif attr == 'idles': gen = dev.generateIdleCode() | |
39 elif attr == 'actions': | |
40 code = dev.generateActionCode() | |
41 if code: | |
42 gen = '''else if (cmd == %(cmdNum)s) { | |
335
3010238b94a0
rgb strip animation support in arduinoNode
drewp@bigasterisk.com
parents:
229
diff
changeset
|
43 { |
3010238b94a0
rgb strip animation support in arduinoNode
drewp@bigasterisk.com
parents:
229
diff
changeset
|
44 %(code)s |
3010238b94a0
rgb strip animation support in arduinoNode
drewp@bigasterisk.com
parents:
229
diff
changeset
|
45 } |
229 | 46 Serial.write('k'); |
47 } | |
48 ''' % dict(cmdNum=devCommandNum[dev.uri], | |
49 code=code) | |
50 else: | |
51 gen = '' | |
52 else: | |
53 raise NotImplementedError | |
54 | |
55 if gen: | |
56 generated[attr] += '// for %s\n%s\n' % (dev.uri, gen.strip()) | |
57 | |
58 code = ''' | |
59 %(includes)s | |
60 | |
61 %(global)s | |
62 byte frame=1; | |
63 unsigned long lastFrame=0; | |
64 | |
65 void setup() { | |
66 Serial.begin(%(baudrate)d); | |
67 Serial.flush(); | |
68 %(setups)s | |
69 } | |
70 | |
71 void idle() { | |
72 // this slowdown is to spend somewhat less time PWMing, to reduce | |
73 // leaking from on channels to off ones (my shift register has no | |
74 // latching) | |
75 if (micros() < lastFrame + 80) { | |
76 return; | |
77 } | |
78 lastFrame = micros(); | |
79 frame++; | |
80 %(idles)s | |
81 } | |
82 | |
83 void loop() { | |
84 byte head, cmd; | |
85 idle(); | |
86 if (Serial.available() >= 2) { | |
87 head = Serial.read(); | |
88 if (head != 0x60) { | |
89 Serial.flush(); | |
90 return; | |
91 } | |
92 cmd = Serial.read(); | |
93 if (cmd == 0x00) { // poll | |
94 %(polls)s | |
95 Serial.write('x'); | |
96 } else if (cmd == 0x01) { // get code checksum | |
97 Serial.write("CODE_CHECKSUM"); | |
98 } | |
99 %(actions)s | |
100 } | |
101 } | |
102 ''' % generated | |
103 return code | |
104 | |
105 def indent(code): | |
106 try: | |
107 with tempfile.SpooledTemporaryFile() as codeFile: | |
108 codeFile.write(code) | |
109 codeFile.seek(0) | |
110 code = subprocess.check_output([ | |
111 'indent', | |
112 '-linux', | |
113 '-fc1', # ok to indent comments | |
114 '-i4', # 4-space indent | |
115 '-sob' # swallow blanks (not working) | |
116 ], stdin=codeFile) | |
117 except OSError as e: | |
118 log.warn("indent failed (%r)", e) | |
119 return code | |
120 |