8e10962718a296c4846b894aa2d11261e9d596ee
[smartthings-infrastructure.git] / Extractor / ExtractorScript.py
1 import os
2 readyToReturn = 0
3 ToReturn = ""
4 eventList = []
5 eventVarMap = {}
6 capabilityMap = {}
7 app1Capabilities = []
8 app2Capabilities = []
9 app1Subscribe = False
10 app2Subscribe = False
11
12 def GetToken(f):
13         global readyToReturn
14         global ToReturn
15         Skip = ['\n', '\t', ' ']
16         Special = ["(", "\"", ":", ",", "{", "}", ")", "/", "*"]
17         S = ""
18         if (readyToReturn):
19                 readyToReturn = 0
20                 return ToReturn
21         ToReturn = ""
22         c = f.read(1)
23         while(True):
24                 if (c in Special):
25                         if (S != ""):
26                                 readyToReturn = 1
27                                 ToReturn = c
28                                 return S
29                         else:
30                                 return c
31                 elif (c in Skip):
32                         if (S != ""):
33                                 return S        
34                         else:
35                                 c = f.read(1)
36                                 continue
37                 S += c
38                 c = f.read(1)
39                 if not c:
40                         return "EOF"
41
42 def ExtractFunctions(F, appName):
43         global eventList
44         global app1Subscribe
45         global app2Subscribe
46         Temp = GetToken(F)
47         while (Temp != "EOF"):
48                 if (Temp == "def" or Temp == "private"):
49                         Temp = GetToken(F)
50                         NameofFunc = Temp
51                         if (GetToken(F) != "="): #We have a function to create object for
52                                 if (appName == "App1"):
53                                         extractedFunctionsApp1.write("//Global Object for functions in subscribe method!\n")    
54                                         extractedFunctionsApp1.write("def %s = this.&" % NameofFunc)
55                                         extractedFunctionsApp1.write("%s\n" % NameofFunc)
56                                 else:
57                                         extractedFunctionsApp2.write("//Global Object for functions in subscribe method!\n")    
58                                         extractedFunctionsApp2.write("def %s = this.&" % NameofFunc)
59                                         extractedFunctionsApp2.write("%s\n" % NameofFunc)
60                 
61                 #Check input capability
62                 if (Temp == "input"):
63                         Temp = GetToken(F) #Get '"'
64                         variable = GetToken(F)
65                         Temp = GetToken(F) #Get '"'
66                         Temp = GetToken(F) #Get ','
67                         Temp = GetToken(F) #Get '"'
68                         Temp = GetToken(F) #Get capability...
69                         capability = Temp
70                         capabilityMap[variable] = capability
71                 
72                 #Check subscribed events
73                 if (Temp == "subscribe"):
74                         if (appName == "App1"):
75                                 app1Subscribe = True
76                         else:
77                                 app2Subscribe = True
78                         Temp = GetToken(F)
79                         variable = Temp
80                         while (Temp != "\"" and Temp != "app" and Temp != "location"):
81                                 Temp = GetToken(F)
82                         if Temp == "\"":
83                                 Temp = GetToken(F)
84                         if Temp not in eventList:
85                                 eventList.append(Temp)
86                                 eventVarMap[Temp] = variable
87
88                 #Check and analyze capabilities for physical interaction
89                 AnalyzeCapabilities(Temp, appName, F)
90
91                 Temp = GetToken(F)
92         
93         #Warn if there is a potential for physical interaction
94         AnalyzePhysicalInteraction(app1Capabilities, app2Capabilities)
95         AnalyzePhysicalInteraction(app2Capabilities, app1Capabilities)
96
97                 
98
99 def AnalyzeCapabilities(Temp, appName, F):
100                         #Illuminance related
101         if (Temp == "capability.switch" or
102                         Temp == "capability.switchLevel" or
103                         Temp == "capability.illuminanceMeasurement" or
104                         Temp == "capability.colorControl" or
105                         #Motion related
106                         Temp == "capability.motionSensor" or
107                         Temp == "capability.accelerationSensor" or
108                         #Water related
109                         Temp == "capability.valve" or
110                         Temp == "capability.waterSensor" or
111                         #Sound related
112                         Temp == "capability.musicPlayer" or
113                         Temp == "capability.alarm" or
114                         Temp == "capability.speechSynthesis" or
115                         Temp == "capability.soundSensor"):
116                 if (appName == "App1"):
117                         app1Capabilities.append(Temp)
118                 else:
119                         app2Capabilities.append(Temp)
120         if (Temp == "capability"):
121                 Temp = GetToken(F) #Get '"'
122                 Temp = GetToken(F) #Get 'Music'
123                 Temp = Temp + GetToken(F) #Get 'Player'
124                 if (Temp == "MusicPlayer"):
125                         if (appName == "App1"):
126                                 app1Capabilities.append("capability.musicPlayer")
127                         else:
128                                 app2Capabilities.append("capability.musicPlayer")
129                         
130 def AnalyzePhysicalInteraction(app1Capab, app2Capab):
131         #Light
132         if ("capability.illuminanceMeasurement" in app1Capab) and ("capability.switch" in app2Capab or 
133                         "capability.switchLevel" in app2Capab or "capability.colorControl" in app2Capab):
134                 print ("\nWARNING: Potential PHYSICAL CONFLICT (light) detected between App1 and App2!\n")
135         #Motion
136         # TODO: Technically this is not entirely precise since we need to be able to detect that the other app creates motion
137         if ("capability.motionSensor" in app1Capab) or ("capability.accelerationSensor" in app1Capab):
138                 print ("\nWARNING: Potential PHYSICAL CONFLICT (motion) detected between App1 and App2!\n")             
139         #Water
140         if ("capability.waterSensor" in app1Capab) and ("capability.valve" in app2Capab or 
141                         "capability.switch" in app2Capab):
142                 print ("\nWARNING: Potential PHYSICAL CONFLICT (water) detected between App1 and App2!\n")
143         #Sound
144         if ("capability.soundSensor" in app1Capab) and ("capability.musicPlayer" in app2Capab or 
145                         "capability.alarm" in app2Capab or "capability.speechSynthesis" in app2Capab):
146                 print ("\nWARNING: Potential PHYSICAL CONFLICT (sound) detected between App1 and App2!\n")
147
148 def ExtractEvents(extractedEvents):
149         global eventList
150         global eventVarMap
151         global capabilityMap
152         extractedEvents.write("while(true) {\n")
153         extractedEvents.write("\tdef eventNumber = Verify.getInt(0,%d)\n" % (len(eventList) - 1))
154         extractedEvents.write("\tswitch(eventNumber) {\n")
155         for i in range(len(eventList)):
156                 extractedEvents.write("\t\tcase %d:\n" % i)
157                 if eventList[i] == "lock":
158                         event = open("eventSimulator/lockEvent.groovy", "r")
159                         for line in event:
160                                 extractedEvents.write(line)
161                         event.close()
162                 elif eventList[i] == "unlock":
163                         event = open("eventSimulator/unlockEvent.groovy", "r")
164                         for line in event:
165                                 extractedEvents.write(line)
166                         event.close()
167                 elif eventList[i] == "contact.open":
168                         event = open("eventSimulator/contactOpenEvent.groovy", "r")
169                         for line in event:
170                                 extractedEvents.write(line)
171                         event.close()
172                 elif eventList[i] == "contact.closed":
173                         event = open("eventSimulator/contactClosedEvent.groovy", "r")
174                         for line in event:
175                                 extractedEvents.write(line)
176                         event.close()
177                 elif eventList[i] == "nfcTouch":
178                         event = open("eventSimulator/nfcTouchEvent.groovy", "r")
179                         for line in event:
180                                 extractedEvents.write(line)
181                         event.close()
182                 elif eventList[i] == "app": #Case for Touched event
183                         event = open("eventSimulator/appTouchEvent.groovy", "r")
184                         for line in event:
185                                 extractedEvents.write(line)
186                         event.close()
187                 elif eventList[i] == "button":
188                         #Write two events subsequently
189                         extractedEvents.write("\t\t\tdef event = Verify.getInt(0,1)\n")
190                         extractedEvents.write("\t\t\tif (event == 0) {\n")
191                         event = open("eventSimulator/buttonPushedEvent.groovy", "r")                    
192                         for line in event:
193                                 extractedEvents.write("\t\t" + line)
194                         event.close()
195                         extractedEvents.write("\t\t\t} else {\n")
196                         event = open("eventSimulator/buttonHeldEvent.groovy", "r")
197                         for line in event:
198                                 extractedEvents.write("\t\t" + line)
199                         event.close()
200                         extractedEvents.write("\t\t\t}\n")
201                 elif eventList[i] == "presence":
202                         #Write two events subsequently
203                         extractedEvents.write("\t\t\tdef event = Verify.getInt(0,1)\n")
204                         extractedEvents.write("\t\t\tif (event == 0) {\n")
205                         event = open("eventSimulator/presencePresentEvent.groovy", "r")                 
206                         for line in event:
207                                 extractedEvents.write("\t\t" + line)
208                         event.close()
209                         extractedEvents.write("\t\t\t} else {\n")
210                         event = open("eventSimulator/presenceLeftEvent.groovy", "r")
211                         for line in event:
212                                 extractedEvents.write("\t\t" + line)
213                         event.close()
214                         extractedEvents.write("\t\t\t}\n")
215                 elif eventList[i] == "doorState":
216                         #Write two events subsequently
217                         extractedEvents.write("\t\t\tdef event = Verify.getInt(0,1)\n")
218                         extractedEvents.write("\t\t\tif (event == 0) {\n")
219                         event = open("eventSimulator/doorOpenEvent.groovy", "r")                        
220                         for line in event:
221                                 extractedEvents.write("\t\t" + line)
222                         event.close()
223                         extractedEvents.write("\t\t\t} else {\n")
224                         event = open("eventSimulator/doorClosedEvent.groovy", "r")
225                         for line in event:
226                                 extractedEvents.write("\t\t" + line)
227                         event.close()
228                         extractedEvents.write("\t\t\t}\n")
229                 elif eventList[i] == "motion":
230                         #Write two events subsequently
231                         extractedEvents.write("\t\t\tdef event = Verify.getInt(0,1)\n")
232                         extractedEvents.write("\t\t\tif (event == 0) {\n")
233                         event = open("eventSimulator/motionActiveEvent.groovy", "r")                    
234                         for line in event:
235                                 extractedEvents.write("\t\t" + line)
236                         event.close()
237                         extractedEvents.write("\t\t\t} else {\n")
238                         event = open("eventSimulator/motionInactiveEvent.groovy", "r")
239                         for line in event:
240                                 extractedEvents.write("\t\t" + line)
241                         event.close()
242                         extractedEvents.write("\t\t\t}\n")
243                 elif eventList[i] == "smoke":
244                         #Write three events subsequently
245                         extractedEvents.write("\t\t\tdef event = Verify.getInt(0,2)\n")
246                         extractedEvents.write("\t\t\tif (event == 0) {\n")
247                         event = open("eventSimulator/smokeClearEvent.groovy", "r")                      
248                         for line in event:
249                                 extractedEvents.write("\t\t" + line)
250                         event.close()
251                         extractedEvents.write("\t\t\t} else if (event == 1) {\n")
252                         event = open("eventSimulator/smokeDetectedEvent.groovy", "r")
253                         for line in event:
254                                 extractedEvents.write("\t\t" + line)
255                         event.close()
256                         extractedEvents.write("\t\t\t} else {\n")
257                         event = open("eventSimulator/smokeTestedEvent.groovy", "r")
258                         for line in event:
259                                 extractedEvents.write("\t\t" + line)
260                         event.close()
261                         extractedEvents.write("\t\t\t}\n")
262                 elif eventList[i] == "carbonMonoxide":
263                         #Check which capability
264                         variable = eventVarMap[eventList[i]]
265                         capability = capabilityMap[variable]
266         
267                         #Write three events subsequently
268                         extractedEvents.write("\t\t\tdef event = Verify.getInt(0,2)\n")
269                         extractedEvents.write("\t\t\tif (event == 0) {\n")                      
270                         if capability == "capability.smokeDetector":
271                                 event = open("eventSimulator/smokeCarbonMonoxideClearEvent.groovy", "r")
272                         elif capability == "capability.carbonMonoxideDetector":
273                                 event = open("eventSimulator/carbonMonoxideClearEvent.groovy", "r")
274                         for line in event:
275                                 extractedEvents.write("\t\t" + line)
276                         event.close()
277                         extractedEvents.write("\t\t\t} else if (event == 1) {\n")
278                         if capability == "capability.smokeDetector":
279                                 event = open("eventSimulator/smokeCarbonMonoxideDetectedEvent.groovy", "r")
280                         elif capability == "capability.carbonMonoxideDetector":
281                                 event = open("eventSimulator/carbonMonoxideDetectedEvent.groovy", "r")
282                         for line in event:
283                                 extractedEvents.write("\t\t" + line)
284                         event.close()
285                         extractedEvents.write("\t\t\t} else {\n")
286                         if capability == "capability.smokeDetector":
287                                 event = open("eventSimulator/smokeCarbonMonoxideTestedEvent.groovy", "r")
288                         elif capability == "capability.carbonMonoxideDetector":
289                                 event = open("eventSimulator/carbonMonoxideTestedEvent.groovy", "r")
290                         for line in event:
291                                 extractedEvents.write("\t\t" + line)
292                         event.close()
293                         extractedEvents.write("\t\t\t}\n")
294                 elif eventList[i] == "battery":
295                         event = open("eventSimulator/batteryChargeEvent.groovy", "r")
296                         for line in event:
297                                 extractedEvents.write(line)
298                         event.close()
299                 elif eventList[i] == "thermostatMode":
300                         #Write five events subsequently
301                         extractedEvents.write("\t\t\tdef event = Verify.getInt(0,4)\n")
302                         extractedEvents.write("\t\t\tif (event == 0) {\n")
303                         event = open("eventSimulator/thermostatAutoModeEvent.groovy", "r")                      
304                         for line in event:
305                                 extractedEvents.write("\t\t" + line)
306                         event.close()
307                         extractedEvents.write("\t\t\t} else if (event == 1) {\n")
308                         event = open("eventSimulator/thermostatCoolModeEvent.groovy", "r")
309                         for line in event:
310                                 extractedEvents.write("\t\t" + line)
311                         event.close()
312                         extractedEvents.write("\t\t\t} else if (event == 2) {\n")
313                         event = open("eventSimulator/thermostatEmergencyHeatModeEvent.groovy", "r")
314                         for line in event:
315                                 extractedEvents.write("\t\t" + line)
316                         event.close()
317                         extractedEvents.write("\t\t\t} else if (event == 3) {\n")
318                         event = open("eventSimulator/thermostatHeatModeEvent.groovy", "r")
319                         for line in event:
320                                 extractedEvents.write("\t\t" + line)
321                         event.close()
322                         extractedEvents.write("\t\t\t} else {\n")
323                         event = open("eventSimulator/thermostatOffModeEvent.groovy", "r")
324                         for line in event:
325                                 extractedEvents.write("\t\t" + line)
326                         event.close()
327                         extractedEvents.write("\t\t\t}\n")
328                 elif eventList[i] == "switch":
329                         #Write two events subsequently
330                         extractedEvents.write("\t\t\tdef event = Verify.getInt(0,1)\n")
331                         extractedEvents.write("\t\t\tif (event == 0) {\n")
332                         event = open("eventSimulator/switchOnEvent.groovy", "r")                        
333                         for line in event:
334                                 extractedEvents.write("\t\t" + line)
335                         event.close()
336                         extractedEvents.write("\t\t\t} else {\n")
337                         event = open("eventSimulator/switchOffEvent.groovy", "r")
338                         for line in event:
339                                 extractedEvents.write("\t\t" + line)
340                         event.close()
341                         extractedEvents.write("\t\t\t}\n")
342                 elif eventList[i] == "location": #Case for Location event
343                         #Write three events subsequently
344                         extractedEvents.write("\t\t\tdef event = Verify.getInt(0,2)\n")
345                         extractedEvents.write("\t\t\tif (event == 0) {\n")
346                         event = open("eventSimulator/locationHomeEvent.groovy", "r")                    
347                         for line in event:
348                                 extractedEvents.write("\t\t" + line)
349                         event.close()
350                         extractedEvents.write("\t\t\t} else if (event == 1) {\n")
351                         event = open("eventSimulator/locationAwayEvent.groovy", "r")
352                         for line in event:
353                                 extractedEvents.write("\t\t" + line)
354                         event.close()
355                         extractedEvents.write("\t\t\t} else {\n")
356                         event = open("eventSimulator/locationNightEvent.groovy", "r")
357                         for line in event:
358                                 extractedEvents.write("\t\t" + line)
359                         event.close()
360                         extractedEvents.write("\t\t\t}\n")
361                 elif eventList[i] == "acceleration":
362                         #Write two events subsequently
363                         extractedEvents.write("\t\t\tdef event = Verify.getInt(0,1)\n")
364                         extractedEvents.write("\t\t\tif (event == 0) {\n")
365                         event = open("eventSimulator/accelerationActiveEvent.groovy", "r")                      
366                         for line in event:
367                                 extractedEvents.write("\t\t" + line)
368                         event.close()
369                         extractedEvents.write("\t\t\t} else {\n")
370                         event = open("eventSimulator/accelerationInactiveEvent.groovy", "r")
371                         for line in event:
372                                 extractedEvents.write("\t\t" + line)
373                         event.close()
374                         extractedEvents.write("\t\t\t}\n")
375                 elif eventList[i] == "beacon":
376                         #Write two events subsequently
377                         extractedEvents.write("\t\t\tdef event = Verify.getInt(0,1)\n")
378                         extractedEvents.write("\t\t\tif (event == 0) {\n")
379                         event = open("eventSimulator/beaconPresenceEvent.groovy", "r")                  
380                         for line in event:
381                                 extractedEvents.write("\t\t" + line)
382                         event.close()
383                         extractedEvents.write("\t\t\t} else {\n")
384                         event = open("eventSimulator/beaconLeftEvent.groovy", "r")
385                         for line in event:
386                                 extractedEvents.write("\t\t" + line)
387                         event.close()
388                         extractedEvents.write("\t\t\t}\n")
389                 elif eventList[i] == "color":
390                         event = open("eventSimulator/colorChangeEvent.groovy", "r")
391                         for line in event:
392                                 extractedEvents.write(line)
393                         event.close()
394                 elif eventList[i] == "hue":
395                         event = open("eventSimulator/hueChangeEvent.groovy", "r")
396                         for line in event:
397                                 extractedEvents.write(line)
398                         event.close()
399                 elif eventList[i] == "saturation":
400                         event = open("eventSimulator/saturationChangeEvent.groovy", "r")
401                         for line in event:
402                                 extractedEvents.write(line)
403                         event.close()
404
405                 ###TODO: Add more events later
406                 extractedEvents.write("\t\t\tbreak\n")
407         extractedEvents.write("\t}\n")
408         extractedEvents.write("}\n")
409         
410 def CheckIfOnlyTouchEvents():
411         #Check and throw an error if it is all touch events
412         #This is called Direct-Direct interaction and we do not model-check for this case
413         onlyTouchEvents = True
414         for item in eventList:
415                 if item != "nfcTouch" and item != "app":
416                         onlyTouchEvents = False
417         if onlyTouchEvents is True and app1Subscribe is True and app2Subscribe is True:
418                 raise Exception("\n\nDirect-Direct Interaction detected: we are skipping this pair...\n\n")
419                 
420 #Extract objects to call functions from App1
421 F1 = open("Extractor/App1/App1.groovy", "r")
422 extractedFunctionsApp1 = open("Extractor/App1/extractedFunctionsApp1.groovy", "w+")
423 ExtractFunctions(F1, "App1")
424 F1.close()
425
426 #Extract objects to call functions from App2
427 F2 = open("Extractor/App2/App2.groovy", "r")
428 extractedFunctionsApp2 = open("Extractor/App2/extractedFunctionsApp2.groovy", "w+")
429 ExtractFunctions(F2, "App2")
430 F2.close()
431
432 #Prepare eventSimulator file while parsing the App1 and App2 files
433 extractedEvents = open("eventSimulator/eventSimulator.groovy", "w+")
434 CheckIfOnlyTouchEvents()
435 ExtractEvents(extractedEvents)
436 extractedEvents.close()
437
438 #Save the extracted methods and app1 in a same file to extract information
439 extractorFile = open("Extractor/extractorFile.groovy", "w+")
440 Extractor = open("Extractor/Extractor.groovy", "r")
441 F1 = open("Extractor/App1/App1.groovy", "r")
442
443 extractorFile.write("////////////////////\n")
444 extractorFile.write("@Field App\n")
445 extractorFile.write("App = \"App1\"")
446 extractorFile.write("\n")
447 for line in Extractor:
448         extractorFile.write(line)
449 extractorFile.write("\n\n")
450 for line in F1:
451         extractorFile.write(line)
452 extractorFile.close()
453 Extractor.close()
454 F1.close()
455 #Run the file to extract the objects
456 os.system("groovy -classpath lib/jpf.jar Extractor/extractorFile.groovy")
457
458
459 #Save the extracted methods and app2 in a same file to extract information
460 extractorFile = open("Extractor/extractorFile.groovy", "w+")
461 Extractor = open("Extractor/Extractor.groovy", "r")
462 F2 = open("Extractor/App2/App2.groovy", "r")
463
464 extractorFile.write("////////////////////\n")
465 extractorFile.write("@Field App\n")
466 extractorFile.write("App = \"App2\"")
467 extractorFile.write("\n")
468 for line in Extractor:
469         extractorFile.write(line)
470 extractorFile.write("\n\n")
471 for line in F2:
472         extractorFile.write(line)
473 #Run the file to extract the objects
474 extractorFile.close()
475 Extractor.close()
476 F2.close()
477 os.system("groovy -classpath lib/jpf.jar Extractor/extractorFile.groovy")
478
479
480
481