Subversion Repositories HomeAutomation

Rev

Rev 2003 | Rev 2127 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
979 linlun 1
#!/usr/bin/python
825 migan 2
 
819 migan 3
# Written by Mattias Runge 2008-05-13
4
 
5
import os
6
import sys
7
import getopt
8
 
852 migan 9
moddir = sys.path[0] + "/../../EmbeddedSoftware/AVR/module"
10
localmoddir = os.getcwd() + "/modules"
819 migan 11
 
12
def getModules():
13
	modules = []
14
	for fileName in os.listdir(moddir):
887 migan 15
		if fileName[0] != '.' and fileName != "template":
819 migan 16
			modules.append(fileName)
17
 
2006 linlun 18
	return sorted(modules, key=str.lower)
819 migan 19
 
20
 
21
def getLocalModules():
22
	modules = []
23
	for fileName in os.listdir(localmoddir):
24
		if fileName[0] != '.':
25
			modules.append(fileName)
26
 
2006 linlun 27
	return sorted(modules, key=str.lower)
819 migan 28
 
29
 
30
def parseModuleIdFromFile(moduleName, fileName):
31
	config_inc = open(fileName, 'r') 
32
	config_inc_lines = config_inc.readlines()
33
	config_inc.close()
1572 linlun 34
	takenIds = []
819 migan 35
	for line in config_inc_lines:
36
		line = line.strip("\n").strip(" ")
827 migan 37
 
819 migan 38
		if line.find(moduleName + "_ID") != -1:
39
			parts = line.split("=")
1572 linlun 40
			if parts[1].strip(" ") != -1 and parts[1].strip(" ") != "<ID>":
41
				takenIds.append(int(parts[1].strip(" "), 16))
2003 linlun 42
				print "Found id: "+parts[1].strip(" ")+" in file: "+fileName+" for module: "+moduleName
1572 linlun 43
	return takenIds
819 migan 44
 
45
 
1572 linlun 46
def getModuleIdsFromFile(moduleName):
819 migan 47
	takenIds = []
1572 linlun 48
	for applicationName in os.listdir("../"):	
819 migan 49
		if applicationName[0] != '.' and os.path.exists("../" + applicationName + "/config.inc"):
1572 linlun 50
			takenIds = parseModuleIdFromFile(moduleName, "../" + applicationName + "/config.inc")
1574 linlun 51
 
1572 linlun 52
	return takenIds
53
 
2006 linlun 54
def parseAllModuleIdFromFile(fileName, foundModules):
55
	index = 0
2003 linlun 56
	modules = getModules()
57
	config_inc = open(fileName, 'r') 
58
	config_inc_lines = config_inc.readlines()
59
	config_inc.close()
2006 linlun 60
	parts = fileName.split("/")
61
	node = parts[1]
2003 linlun 62
	for line in config_inc_lines:
63
		line = line.strip("\n").strip(" ")
64
 
65
		if line.find("_ID") != -1:
66
			parts = line.split("=")
67
			if (parts[0][:-3] in modules):
68
				if parts[1].strip(" ") != -1 and parts[1].strip(" ") != "<ID>":
2006 linlun 69
					if (foundModules == 0):
70
						print "\tModule: "+parts[0][:-3]+"\t"+parts[1].strip(" ")
71
					else:
72
						foundModules.append(parts[0][:-3]+"$"+node+"$"+parts[1].strip(" ")) 
73
 
74
	return foundModules
2003 linlun 75
 
76
def getAllModuleIdsFromFile():
2006 linlun 77
	foundModules = []
2003 linlun 78
	for applicationName in os.listdir("../"):	
79
		if applicationName[0] != '.' and os.path.exists("../" + applicationName + "/config.inc"):
2006 linlun 80
			parseAllModuleIdFromFile("../" + applicationName + "/config.inc", foundModules)
81
 
82
	foundModulesSorted = sorted(foundModules, key=str.lower)
83
	lastModule = ""
84
	for x in foundModulesSorted:
85
		splitted = x.split("$")
86
		if (lastModule != splitted[0]):
87
			lastModule = splitted[0]
88
			print lastModule
89
		print "%20s :" % splitted[1],
90
		print splitted[2]
91
 
92
def getAllNodesFromFile():
93
	files = sorted(os.listdir("../"), key=str.lower)
94
	for applicationName in files:	
95
		if applicationName[0] != '.' and os.path.exists("../" + applicationName + "/config.inc"):
2003 linlun 96
			print "Found node: "+applicationName
2006 linlun 97
			parseAllModuleIdFromFile("../" + applicationName + "/config.inc", 0)
819 migan 98
 
1572 linlun 99
def getFreeModuleId(takenIds):
819 migan 100
	if len(takenIds) == 0:
1572 linlun 101
		return 1
819 migan 102
	takenIds.sort()
103
 
104
	lastId = 0
105
 
106
	for takenId in takenIds:
107
		if takenId != lastId+1:
1572 linlun 108
			return lastId+1
827 migan 109
		lastId = takenId
819 migan 110
 
1572 linlun 111
	return lastId+1
819 migan 112
 
1572 linlun 113
 
114
 
819 migan 115
def compileMainFile():
116
	print "Compiling new main.c..."
117
	main_c_template = open('src/main.c.template', 'r') 
118
	main_c_template_lines = main_c_template.readlines()
119
	main_c_template.close()
120
 
121
	modules = getLocalModules()
122
 
123
	main_c = open('src/main.c', 'w') 
124
 
125
	for main_c_template_line in main_c_template_lines:
126
		pos_include = main_c_template_line.find('%INCLUDE')
127
		pos_init = main_c_template_line.find('%INIT')
128
		pos_process = main_c_template_line.find('%PROCESS')
129
		pos_list = main_c_template_line.find('%LIST')
130
		pos_handlemsg = main_c_template_line.find('%HANDLEMSG')
131
 
132
		if pos_include != -1:
133
			for moduleName in modules:
822 migan 134
				main_c.write(main_c_template_line[:pos_include] + "#include \"../modules/" + moduleName + "/" + moduleName + ".h\"\n")
819 migan 135
		elif pos_init != -1:
136
			for moduleName in modules:
839 migan 137
				main_c.write(main_c_template_line[:pos_init] + moduleName + "_Init();\n")
819 migan 138
		elif pos_process != -1:
139
			for moduleName in modules:
839 migan 140
				main_c.write(main_c_template_line[:pos_process] + moduleName + "_Process();\n")
819 migan 141
		elif pos_list != -1:
142
			count = 1
143
			for moduleName in modules:
839 migan 144
				main_c.write(main_c_template_line[:pos_list] + moduleName + "_List(" + str(count) + ");\n")
819 migan 145
				count += 1
146
		elif pos_handlemsg != -1:
147
			for moduleName in modules:
839 migan 148
				main_c.write(main_c_template_line[:pos_handlemsg] + moduleName + "_HandleMessage(&rxMsg);\n")
819 migan 149
		else:
150
			main_c.write(main_c_template_line)
151
 
152
	main_c.close()
153
 
154
	print "Creation of main.c complete"
155
 
156
def readConfigSection(fileName, sectionName):
157
	fileInstance = open(fileName, 'r')
158
	lines = fileInstance.readlines()
159
	fileInstance.close()
160
 
161
	sectionLines = []
162
 
163
	inSection = False
164
 
165
	for line in lines:
166
		if not inSection:
1727 cougar 167
			if line.find("## Section " + sectionName + " --") != -1:
819 migan 168
				inSection = True
169
				sectionLines.append(line.strip("\n"))
170
		else:
1727 cougar 171
			if line.find("## End section " + sectionName + " --") != -1:
819 migan 172
				inSection = False
173
 
174
			sectionLines.append(line.strip("\n"))
175
 
176
	return sectionLines
177
 
178
 
179
def updateConfigFile():
180
	print "Updating config.inc..."
181
	modules = getLocalModules()
182
	moduleSections = {}
183
	applicationSection = []
1574 linlun 184
	moduleName="none"
819 migan 185
	if not os.path.exists("config.inc"):
186
		applicationSection = readConfigSection("src/config.inc.template", "application")
187
 
188
		for moduleName in modules:
189
			moduleSections[moduleName] = readConfigSection(localmoddir + "/" + moduleName + "/config.inc.template", moduleName)
190
	else:
191
		applicationSection = readConfigSection("config.inc", "application")
192
 
193
		for moduleName in modules:
194
			moduleSections[moduleName] = readConfigSection("config.inc", moduleName)
195
 
196
			if len(moduleSections[moduleName]) <= 1:
197
				moduleSections[moduleName] = readConfigSection(localmoddir + "/" + moduleName + "/config.inc.template", moduleName)
198
 
199
	timers = 0
1125 linlun 200
	pcints = 0
1572 linlun 201
 
202
	moduleIds = getModuleIdsFromFile(moduleName)
203
 
819 migan 204
	for moduleName, moduleSection in moduleSections.iteritems():
205
		c = 0
206
		for line in moduleSection:
1259 runge 207
			if len(line) > 0:
208
				if line[0] != '#':
209
					if line.find("<ID>") != -1:
1572 linlun 210
						new_ID = getFreeModuleId(moduleIds)
211
						print "id = "+hex(new_ID)
212
						moduleIds.append(new_ID)
213
						line = line.replace("<ID>", hex(new_ID))
1259 runge 214
					elif line.find("<TIMER>") != -1:
215
						line = line[:line.find("=")+1] + hex(timers) + " /* <TIMER> -- DO NOT REMOVE THIS COMMENT -- */"
216
						timers += 1
217
					elif line.find("<PCINT>") != -1:
218
						line = line[:line.find("=")+1] + hex(pcints) + " /* <PCINT> -- DO NOT REMOVE THIS COMMENT -- */"
219
						pcints += 1
220
 
221
			moduleSection[c] = line;
222
			c += 1
223
 
224
	c = 0
225
	for line in applicationSection:
226
		if len(line) > 0:
1258 runge 227
			if line[0] != '#':
1259 runge 228
				if line.find("<TIMER>") != -1:
1258 runge 229
					line = line[:line.find("=")+1] + hex(timers) + " /* <TIMER> -- DO NOT REMOVE THIS COMMENT -- */"
230
					timers += 1
1259 runge 231
				elif line.find("TIMER_NUM_TIMERS=") != -1:
232
					line = "TIMER_NUM_TIMERS=" + hex(timers)
233
				elif line.find("NUMBER_OF_MODULES=") != -1:
234
					line = "NUMBER_OF_MODULES=" + hex(len(modules))
1258 runge 235
				elif line.find("<PCINT>") != -1:
236
					line = line[:line.find("=")+1] + hex(pcints) + " /* <PCINT> -- DO NOT REMOVE THIS COMMENT -- */"
237
					pcints += 1
1259 runge 238
				elif line.find("PCINT_NUM_PCINTS=") != -1:
239
					line = "PCINT_NUM_PCINTS=" + hex(pcints)
819 migan 240
		applicationSection[c] = line;
241
		c += 1
242
 
243
	config_inc = open('config.inc', 'w')
244
 
245
	for line in applicationSection:
246
		config_inc.write(line + "\n")
247
 
248
	for moduleName, moduleSection in moduleSections.iteritems():
249
		for line in moduleSection:
250
			config_inc.write(line + "\n")
251
 
252
	config_inc.close()
253
 
254
	print "Update of config.inc complete"
255
 
256
 
257
def compileSourcesFile():
258
	print "Compiling sources.inc..."
259
 
260
	uniqueSet = []
1983 linlun 261
	uniqueSet2 = []
1991 linlun 262
	if os.path.isfile("src/libraries.list.template"):
263
		libraries_list_template = open('src/libraries.list.template', 'r')
264
		libraries_list_template_lines = libraries_list_template.readlines()
265
		libraries_list_template.close()
819 migan 266
 
267
	sources_list_template = open('src/sources.list.template', 'r')
268
	sources_list_template_lines = sources_list_template.readlines()
269
	sources_list_template.close()
1991 linlun 270
	if os.path.isfile("src/libraries.list.template"):
271
		for libraries_list_template_line in libraries_list_template_lines:
272
			line =libraries_list_template_line.strip("\n").strip(" ")
273
			if len(line) > 0:
274
				if line[0] != '#':
275
					uniqueSet2.append(line)
819 migan 276
 
277
	for sources_list_template_line in sources_list_template_lines:
847 migan 278
		line = sources_list_template_line.strip("\n").strip(" ")
279
		if len(line) > 0:
280
			if line[0] != '#':
281
				uniqueSet.append(line)
819 migan 282
 
283
	modules = getLocalModules()
284
 
285
	for moduleName in modules:
286
		sources_list = open(localmoddir + "/" + moduleName + "/sources.list", 'r')
287
		sources_list_lines = sources_list.readlines()
288
		sources_list.close()
289
 
1993 linlun 290
		if os.path.isfile(localmoddir + "/" + moduleName + "/libraries.list"):
291
			libraries_list = open(localmoddir + "/" + moduleName + "/libraries.list", 'r')
292
			libraries_list_lines = libraries_list.readlines()
293
			libraries_list.close()
294
 
295
			for libraries_list_line in libraries_list_lines:
296
				line = libraries_list_line.strip("\n").strip(" ")
297
				if len(line) > 0:
298
					if line[0] != '#':
299
						uniqueSet2.append("../../../module/" + moduleName + line)
819 migan 300
		for sources_list_line in sources_list_lines:
847 migan 301
			line = sources_list_line.strip("\n").strip(" ")
302
			if len(line) > 0:
303
				if line[0] != '#':
304
					uniqueSet.append(line)
305
 
819 migan 306
 
307
	sourcesString = "SOURCES = "
308
 
309
	#FIXME: Make uniqueSet actually unique
310
 
311
	for line in uniqueSet:
312
		sourcesString += line + " "
1983 linlun 313
	sourcesString += "\n"
314
	sourcesString += "LDLIBS = "
1993 linlun 315
	for line in uniqueSet2:
316
		sourcesString += line + " "
819 migan 317
	sources_inc = open('sources.inc', 'w')
318
	sources_inc.write(sourcesString.strip(" ") + "\n")
319
	sources_inc.close()
320
 
321
	print "Creation of sources.inc complete"
322
 
323
def regenerateModules():
324
	print "Regenerating modules..."
836 migan 325
	print ""
819 migan 326
	compileSourcesFile()
836 migan 327
	print ""
819 migan 328
	compileMainFile()
836 migan 329
	print ""
819 migan 330
	updateConfigFile()
836 migan 331
	print ""
819 migan 332
	print "Regenerating modules complete"
836 migan 333
	print ""
819 migan 334
 
2003 linlun 335
def listUsedModules():
336
	print "Listing modules..."
337
	print ""
338
	getAllModuleIdsFromFile()
339
	print ""
340
	print "Listing modules complete"
341
	print ""
2006 linlun 342
 
343
def listUsedNodes():
344
	print "Listing nodes..."
345
	print ""
346
	getAllNodesFromFile()
347
	print ""
348
	print "Listing nodes complete"
349
	print ""
819 migan 350
 
351
def addModule(moduleName):
352
	print "Trying to add module " + moduleName
353
 
354
	try:
1935 arune 355
		# the following creates symlinks to <path to modulemanager>/../../EmbeddedSoftware/AVR/module
356
		# and <path to modulemanager> is an absolute path which makes the symlink similar to this:
357
		# act_dimmer230 -> /home/arune/Documents/HomeAutomation/PcSoftware/scripts/../../EmbeddedSoftware/AVR/module/act_dimmer230
358
		#os.symlink(moddir + "/" + moduleName, localmoddir + "/" + moduleName)
359
		# instead symlink to relative path instead
360
		os.symlink("../../../module/" + moduleName, localmoddir + "/" + moduleName)
820 migan 361
		print "Added module successfully"
819 migan 362
	except OSError, (errno, strerror):
363
		if errno == 17:
364
			print "A link, file or directory named " + moduleName + " is already present in the modules directory, not linking"
365
		else:
366
			raise
367
 
368
	print ""
369
 
370
	regenerateModules()
371
 
372
 
824 migan 373
def delModule(moduleName):
374
	print "Trying to remove module " + moduleName
375
 
376
	try:
377
		os.unlink(localmoddir + "/" + moduleName)
378
		print "Removed module successfully"
379
	except OSError, (errno, strerror):
380
		if errno == 2:
381
			print "No such " + moduleName + " present in the modules directory, not unlinking"
382
		else:
383
			raise
384
 
385
	print ""
386
 
387
	regenerateModules()
388
 
852 migan 389
def createFile(moduleName, templateFileName, moduleFileName):
390
	print "Creating " + moduleName + "/" + templateFileName + "..."
391
	template_file = open(moddir + "/template/" + templateFileName, 'r')
392
	lines = template_file.readlines()
393
	template_file.close()
824 migan 394
 
852 migan 395
	module_file = open(moddir + "/" + moduleName + "/" + moduleFileName, 'w')
396
 
397
	for line in lines:
398
		line = line.replace("<template>", moduleName)
399
		line = line.replace("<TEMPLATE>", moduleName.upper())
400
 
401
		module_file.write(line)
402
 
403
	module_file.close()
404
 
405
def newModule(moduleName):
406
	print "Creating " + moddir + "/" + moduleName + " directory..."
407
	os.mkdir(moddir + "/" + moduleName + "/")
408
 
409
	createFile(moduleName, "config.inc.template", "config.inc.template")
410
	createFile(moduleName, "sources.list", "sources.list")
411
	createFile(moduleName, "template.h", moduleName + ".h")
412
	createFile(moduleName, "template.c", moduleName + ".c")
1106 linlun 413
	createFile(moduleName, "template_eeprom.h", moduleName + "_eeprom.h")
852 migan 414
 
819 migan 415
def usage():
836 migan 416
	print "Syntax: ./ModuleManager [options]"
819 migan 417
	print "Options:"
836 migan 418
	print "  --help               Print this help"
419
	print "  --regenerate         Regenarate modules and files"
420
	print "  --list               List avalible and installed modules"
421
	print "  --add=<module name>  Adds a module to the application"
422
	print "  --del=<module name>  Removes a module from the application"
852 migan 423
	print "  --new=<module name>  Creates a new module from the module template"
2003 linlun 424
	print "  --modules            Lists all used modules in your personal folder"
2006 linlun 425
	print "  --nodes              Lists all nodes in your personal folder"
819 migan 426
	print ""
427
 
428
 
429
def main():
430
	try:
2006 linlun 431
		opts, args = getopt.getopt(sys.argv[1:], "hlrcmn", ["help", "list", "modules", "nodes", "regenerate", "add=", "del=", "new="])
819 migan 432
	except getopt.GetoptError, err:
433
		# print help information and exit:
434
		print str(err) # will print something like "option -a not recognized"
435
		usage()
436
		sys.exit(2)
825 migan 437
 
438
	if len(sys.argv) == 1:
439
		usage()
440
		sys.exit()
441
 
819 migan 442
	for o, a in opts:
885 migan 443
		if o in ("-c"):
836 migan 444
			modules = getModules()
824 migan 445
 
885 migan 446
			for module in modules:
447
				print module
448
 
449
		elif o in ("-l", "--list"):
450
			modules = getModules()
836 migan 451
			print "Available modules"
452
			print "================="
453
			for module in modules:
454
				print module
455
 
885 migan 456
 
457
			if os.path.exists(localmoddir):
458
				print ""
836 migan 459
 
885 migan 460
				modules = getLocalModules()
836 migan 461
 
885 migan 462
				print "Modules used in this application"
463
				print "================================"
464
				for module in modules:
465
					print module
466
 
819 migan 467
		elif o in ("-h", "--help"):
468
			usage()
469
			sys.exit()
824 migan 470
 
819 migan 471
		elif o in ("-r", "--regenerate"):
472
			regenerateModules()
824 migan 473
 
2003 linlun 474
		elif o in ("-m", "--modules"):
475
			listUsedModules()
2006 linlun 476
 
477
		elif o in ("-n", "--nodes"):
478
			listUsedNodes()
2003 linlun 479
 
819 migan 480
		elif o in ("--add"):
481
			if len(a) == 0:
482
				print "No modulename specified"
483
				usage()
484
				sys.exit()
485
 
486
			if a not in getModules():
487
				print a + " is not a recognized module name"
488
				sys.exit()
489
 
490
			addModule(a)
824 migan 491
 
492
		elif o in ("--del"):
493
			if len(a) == 0:
494
				print "No modulename specified"
495
				usage()
496
				sys.exit()
497
 
498
			if a not in getModules():
499
				print a + " is not a recognized module name"
500
				sys.exit()
501
 
502
			delModule(a)
503
 
852 migan 504
		elif o in ("--new"):
505
			if len(a) == 0:
506
				print "No modulename specified"
507
				usage()
508
				sys.exit()
509
 
510
			if a in getModules():
511
				print a + " already exists"
512
				sys.exit()
513
 
514
			newModule(a)
515
 
819 migan 516
		else:
517
			assert False, "unhandled option"
518
 
519
 
520
if __name__ == "__main__":
521
	main()
522