Added physical interaction detection into the build flow.
[smartthings-infrastructure.git] / Extractor / ExtractorScript.py
1 import os
2 readyToReturn = 0
3 ToReturn = ""
4 eventMap = []
5 app1Capabilities = []
6 app2Capabilities = []
7
8 def GetToken(f):
9         global readyToReturn
10         global ToReturn
11         Skip = ['\n', '\t', ' ']
12         Special = ["(", "\"", ":", ",", "{", "}", ")", "/", "*"]
13         S = ""
14         if (readyToReturn):
15                 readyToReturn = 0
16                 return ToReturn
17         ToReturn = ""
18         c = f.read(1)
19         while(True):
20                 if (c in Special):
21                         if (S != ""):
22                                 readyToReturn = 1
23                                 ToReturn = c
24                                 return S
25                         else:
26                                 return c
27                 elif (c in Skip):
28                         if (S != ""):
29                                 return S        
30                         else:
31                                 c = f.read(1)
32                                 continue
33                 S += c
34                 c = f.read(1)
35                 if not c:
36                         return "EOF"
37
38 def ExtractFunctions(F, appName):
39         global eventMap
40         Temp = GetToken(F)
41         while (Temp != "EOF"):
42                 if (Temp == "def" or Temp == "private"):
43                         Temp = GetToken(F)
44                         NameofFunc = Temp
45                         if (GetToken(F) != "="): #We have a function to create object for
46                                 if (appName == "App1"):
47                                         extractedFunctionsApp1.write("//Global Object for functions in subscribe method!\n")    
48                                         extractedFunctionsApp1.write("def %s = this.&" % NameofFunc)
49                                         extractedFunctionsApp1.write("%s\n" % NameofFunc)
50                                 else:
51                                         extractedFunctionsApp2.write("//Global Object for functions in subscribe method!\n")    
52                                         extractedFunctionsApp2.write("def %s = this.&" % NameofFunc)
53                                         extractedFunctionsApp2.write("%s\n" % NameofFunc)
54                 
55                 #Check subscribed events
56                 if (Temp == "subscribe"):
57                         counter = 0
58                         while (counter < 5 and Temp != "\""):
59                                 Temp = GetToken(F)
60                                 counter = counter + 1
61                         Temp = GetToken(F)
62                         #If counter >= 5 that means it is not found, so it must be appTouch
63                         if (counter >= 5):
64                                 Temp = "Touched"
65                         eventMap.append(Temp)
66                         Temp = GetToken(F)
67         
68                 #Check and analyze capabilities for physical interaction
69                 AnalyzeCapabilities(Temp, appName)
70                 Temp = GetToken(F)
71         
72         #Warn if there is a potential for physical interaction
73         AnalyzePhysicalInteraction(app1Capabilities, app2Capabilities)
74         AnalyzePhysicalInteraction(app2Capabilities, app1Capabilities)
75
76 def AnalyzeCapabilities(Temp, appName):
77                         #Illuminance related
78         if (Temp == "capability.switch" or
79                         Temp == "capability.switchLevel" or
80                         Temp == "capability.illuminanceMeasurement" or
81                         #Motion related
82                         Temp == "capability.motionSensor" or
83                         #Water related
84                         Temp == "capability.valve" or
85                         Temp == "capability.waterSensor" or
86                         #Sound related
87                         Temp == "capability.musicPlayer" or
88                         Temp == "capability.alarm" or
89                         Temp == "capability.speechSynthesis" or
90                         Temp == "capability.soundSensor"):
91                 if (appName == "App1"):
92                         app1Capabilities.append(Temp)
93                 else:
94                         app2Capabilities.append(Temp)
95                         
96 def AnalyzePhysicalInteraction(app1Capab, app2Capab):
97         #Light
98         if ("capability.illuminanceMeasurement" in app1Capab) and ("capability.switch" in app2Capab or 
99                         "capability.switchLevel" in app2Capab):
100                 print ("\nWARNING: Potential PHYSICAL CONFLICT (light) detected between App1 and App2!\n")
101         #Motion
102         if ("capability.motionSensor" in app1Capab):
103                 print ("\nWARNING: Potential PHYSICAL CONFLICT (motion) detected between App1 and App2!\n")             
104         #Water
105         if ("capability.waterSensor" in app1Capab) and ("capability.valve" in app2Capab or 
106                         "capability.switch" in app2Capab):
107                 print ("\nWARNING: Potential PHYSICAL CONFLICT (water) detected between App1 and App2!\n")
108         #Sound
109         if ("capability.soundSensor" in app1Capab) and ("capability.musicPlayer" in app2Capab or 
110                         "capability.alarm" in app2Capab or "capability.speechSynthesis" in app2Capab):
111                 print ("\nWARNING: Potential PHYSICAL CONFLICT (sound) detected between App1 and App2!\n")
112                         
113 def ExtractEvents(extractedEvents):
114         global eventMap
115         extractedEvents.write("Random random = new Random(42)\n")
116         extractedEvents.write("counter = 1000\n")
117         extractedEvents.write("while(counter > 0) {\n")
118         extractedEvents.write("\tdef eventNumber = random.nextInt(%d)\n" % (len(eventMap) - 1))
119         extractedEvents.write("\tswitch(eventNumber) {\n")
120         eventCounter = 0;
121         for i in range(len(eventMap)):
122                 extractedEvents.write("\t\tcase %d:\n" % eventCounter)
123                 if eventMap[i] == "lock":
124                         event = open("eventSimulator/lockEvent.groovy", "r")
125                         for line in event:
126                                 extractedEvents.write(line)
127                         event.close()
128                 elif eventMap[i] == "unlock":
129                         event = open("eventSimulator/unlockEvent.groovy", "r")
130                         for line in event:
131                                 extractedEvents.write(line)
132                         event.close()
133                 elif eventMap[i] == "contact.open":
134                         event = open("eventSimulator/contactOpenEvent.groovy", "r")
135                         for line in event:
136                                 extractedEvents.write(line)
137                         event.close()
138                 elif eventMap[i] == "contact.closed":
139                         event = open("eventSimulator/contactClosedEvent.groovy", "r")
140                         for line in event:
141                                 extractedEvents.write(line)
142                         event.close()
143                 elif eventMap[i] == "switch.on":
144                         event = open("eventSimulator/switchOnEvent.groovy", "r")
145                         for line in event:
146                                 extractedEvents.write(line)
147                         event.close()
148                 elif eventMap[i] == "switch.off":
149                         event = open("eventSimulator/switchOffEvent.groovy", "r")
150                         for line in event:
151                                 extractedEvents.write(line)
152                         event.close()
153                 elif eventMap[i] == "nfcTouch":
154                         event = open("eventSimulator/nfcTouchEvent.groovy", "r")
155                         for line in event:
156                                 extractedEvents.write(line)
157                         event.close()
158                 elif eventMap[i] == "Touched":
159                         event = open("eventSimulator/appTouchEvent.groovy", "r")
160                         for line in event:
161                                 extractedEvents.write(line)
162                         event.close()
163                 elif eventMap[i] == "button":
164                         #Write two events subsequently
165                         event = open("eventSimulator/buttonPushedEvent.groovy", "r")
166                         for line in event:
167                                 extractedEvents.write(line)
168                         event.close()
169                         extractedEvents.write("\t\t\tbreak\n")
170                         eventCounter = eventCounter + 1
171                         extractedEvents.write("\t\tcase %d:\n" % eventCounter)
172                         event = open("eventSimulator/buttonHeldEvent.groovy", "r")
173                         for line in event:
174                                 extractedEvents.write(line)
175                         event.close()
176                 elif eventMap[i] == "presence":
177                         #Write two events subsequently
178                         event = open("eventSimulator/presencePresentEvent.groovy", "r")
179                         for line in event:
180                                 extractedEvents.write(line)
181                         event.close()
182                         extractedEvents.write("\t\t\tbreak\n")
183                         eventCounter = eventCounter + 1
184                         extractedEvents.write("\t\tcase %d:\n" % eventCounter)
185                         event = open("eventSimulator/presenceLeftEvent.groovy", "r")
186                         for line in event:
187                                 extractedEvents.write(line)
188                         event.close()
189                 elif eventMap[i] == "doorState":
190                         #Write two events subsequently
191                         event = open("eventSimulator/doorOpenEvent.groovy", "r")
192                         for line in event:
193                                 extractedEvents.write(line)
194                         event.close()
195                         extractedEvents.write("\t\t\tbreak\n")
196                         eventCounter = eventCounter + 1
197                         extractedEvents.write("\t\tcase %d:\n" % eventCounter)
198                         event = open("eventSimulator/doorClosedEvent.groovy", "r")
199                         for line in event:
200                                 extractedEvents.write(line)
201                         event.close()
202                 eventCounter = eventCounter + 1
203
204                 ###TODO: Add more events later
205                 extractedEvents.write("\n\t\t\tbreak\n")
206         extractedEvents.write("\t}\n")
207         extractedEvents.write("\tcounter--\n")
208         extractedEvents.write("}\n")
209                 
210 #Extract objects to call functions from App1
211 F1 = open("Extractor/App1/App1.groovy", "r")
212 extractedFunctionsApp1 = open("Extractor/App1/extractedFunctionsApp1.groovy", "w+")
213 ExtractFunctions(F1, "App1")
214 F1.close()
215
216 #Extract objects to call functions from App2
217 F2 = open("Extractor/App2/App2.groovy", "r")
218 extractedFunctionsApp2 = open("Extractor/App2/extractedFunctionsApp2.groovy", "w+")
219 ExtractFunctions(F2, "App2")
220 F2.close()
221
222 #Prepare eventSimulator file while parsing the App1 and App2 files
223 extractedEvents = open("eventSimulator/eventSimulator.groovy", "w+")
224 ExtractEvents(extractedEvents)
225 extractedEvents.close()
226
227 #Save the extracted methods and app1 in a same file to extract information
228 extractorFile = open("Extractor/extractorFile.groovy", "w+")
229 Extractor = open("Extractor/Extractor.groovy", "r")
230 F1 = open("Extractor/App1/App1.groovy", "r")
231
232 extractorFile.write("////////////////////\n")
233 extractorFile.write("@Field App\n")
234 extractorFile.write("App = \"App1\"")
235 extractorFile.write("\n")
236 for line in Extractor:
237         extractorFile.write(line)
238 extractorFile.write("\n\n")
239 for line in F1:
240         extractorFile.write(line)
241 extractorFile.close()
242 Extractor.close()
243 F1.close()
244 #Run the file to extract the objects
245 os.system("groovy Extractor/extractorFile.groovy")
246
247
248 #Save the extracted methods and app2 in a same file to extract information
249 extractorFile = open("Extractor/extractorFile.groovy", "w+")
250 Extractor = open("Extractor/Extractor.groovy", "r")
251 F2 = open("Extractor/App2/App2.groovy", "r")
252
253 extractorFile.write("////////////////////\n")
254 extractorFile.write("@Field App\n")
255 extractorFile.write("App = \"App2\"")
256 extractorFile.write("\n")
257 for line in Extractor:
258         extractorFile.write(line)
259 extractorFile.write("\n\n")
260 for line in F2:
261         extractorFile.write(line)
262 #Run the file to extract the objects
263 extractorFile.close()
264 Extractor.close()
265 F2.close()
266 os.system("groovy Extractor/extractorFile.groovy")
267
268
269
270