Subversion Repositories HomeAutomation

Rev

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