Adding more features for physical interaction detection and warning.
[smartthings-infrastructure.git] / Extractor / ExtractorScript.py
index 11486bc7301702d1bc5b901f27af3cd275d015e6..974afc453933e8c6f2dd0921524127d3465f4cfe 100644 (file)
@@ -1,9 +1,13 @@
 import os
 readyToReturn = 0
 ToReturn = ""
-eventMap = []
+eventList = []
+eventVarMap = {}
+capabilityMap = {}
 app1Capabilities = []
 app2Capabilities = []
+app1Subscribe = False
+app2Subscribe = False
 
 def GetToken(f):
        global readyToReturn
@@ -36,7 +40,9 @@ def GetToken(f):
                        return "EOF"
 
 def ExtractFunctions(F, appName):
-       global eventMap
+       global eventList
+       global app1Subscribe
+       global app2Subscribe
        Temp = GetToken(F)
        while (Temp != "EOF"):
                if (Temp == "def" or Temp == "private"):
@@ -52,17 +58,35 @@ def ExtractFunctions(F, appName):
                                        extractedFunctionsApp2.write("def %s = this.&" % NameofFunc)
                                        extractedFunctionsApp2.write("%s\n" % NameofFunc)
                
+               #Check input capability
+               if (Temp == "input"):
+                       Temp = GetToken(F) #Get '"'
+                       variable = GetToken(F)
+                       Temp = GetToken(F) #Get '"'
+                       Temp = GetToken(F) #Get ','
+                       Temp = GetToken(F) #Get '"'
+                       Temp = GetToken(F) #Get capability...
+                       capability = Temp
+                       capabilityMap[variable] = capability
+               
                #Check subscribed events
                if (Temp == "subscribe"):
+                       if (appName == "App1"):
+                               app1Subscribe = True
+                       else:
+                               app2Subscribe = True
+                       Temp = GetToken(F)
+                       variable = Temp
                        while (Temp != "\"" and Temp != "app" and Temp != "location"):
                                Temp = GetToken(F)
                        if Temp == "\"":
                                Temp = GetToken(F)
-                       if Temp not in eventMap:
-                               eventMap.append(Temp)
+                       if Temp not in eventList:
+                               eventList.append(Temp)
+                               eventVarMap[Temp] = variable
 
                #Check and analyze capabilities for physical interaction
-               AnalyzeCapabilities(Temp, appName)
+               AnalyzeCapabilities(Temp, appName, F)
 
                Temp = GetToken(F)
        
@@ -72,7 +96,7 @@ def ExtractFunctions(F, appName):
 
                
 
-def AnalyzeCapabilities(Temp, appName):
+def AnalyzeCapabilities(Temp, appName, F):
                        #Illuminance related
        if (Temp == "capability.switch" or
                        Temp == "capability.switchLevel" or
@@ -91,6 +115,15 @@ def AnalyzeCapabilities(Temp, appName):
                        app1Capabilities.append(Temp)
                else:
                        app2Capabilities.append(Temp)
+       if (Temp == "capability"):
+               Temp = GetToken(F) #Get '"'
+               Temp = GetToken(F) #Get 'Music'
+               Temp = Temp + GetToken(F) #Get 'Player'
+               if (Temp == "MusicPlayer"):
+                       if (appName == "App1"):
+                               app1Capabilities.append("capability.musicPlayer")
+                       else:
+                               app2Capabilities.append("capability.musicPlayer")
                        
 def AnalyzePhysicalInteraction(app1Capab, app2Capab):
        #Light
@@ -110,44 +143,45 @@ def AnalyzePhysicalInteraction(app1Capab, app2Capab):
                print ("\nWARNING: Potential PHYSICAL CONFLICT (sound) detected between App1 and App2!\n")
 
 def ExtractEvents(extractedEvents):
-       global eventMap
-       #extractedEvents.write("while(true) {\n")
-       extractedEvents.write("for(int i=0; i<100; i++) {\n")
-       extractedEvents.write("\tdef eventNumber = Verify.getInt(0,%d)\n" % (len(eventMap) - 1))
+       global eventList
+       global eventVarMap
+       global capabilityMap
+       extractedEvents.write("while(true) {\n")
+       extractedEvents.write("\tdef eventNumber = Verify.getInt(0,%d)\n" % (len(eventList) - 1))
        extractedEvents.write("\tswitch(eventNumber) {\n")
-       for i in range(len(eventMap)):
+       for i in range(len(eventList)):
                extractedEvents.write("\t\tcase %d:\n" % i)
-               if eventMap[i] == "lock":
+               if eventList[i] == "lock":
                        event = open("eventSimulator/lockEvent.groovy", "r")
                        for line in event:
                                extractedEvents.write(line)
                        event.close()
-               elif eventMap[i] == "unlock":
+               elif eventList[i] == "unlock":
                        event = open("eventSimulator/unlockEvent.groovy", "r")
                        for line in event:
                                extractedEvents.write(line)
                        event.close()
-               elif eventMap[i] == "contact.open":
+               elif eventList[i] == "contact.open":
                        event = open("eventSimulator/contactOpenEvent.groovy", "r")
                        for line in event:
                                extractedEvents.write(line)
                        event.close()
-               elif eventMap[i] == "contact.closed":
+               elif eventList[i] == "contact.closed":
                        event = open("eventSimulator/contactClosedEvent.groovy", "r")
                        for line in event:
                                extractedEvents.write(line)
                        event.close()
-               elif eventMap[i] == "nfcTouch":
+               elif eventList[i] == "nfcTouch":
                        event = open("eventSimulator/nfcTouchEvent.groovy", "r")
                        for line in event:
                                extractedEvents.write(line)
                        event.close()
-               elif eventMap[i] == "app": #Case for Touched event
+               elif eventList[i] == "app": #Case for Touched event
                        event = open("eventSimulator/appTouchEvent.groovy", "r")
                        for line in event:
                                extractedEvents.write(line)
                        event.close()
-               elif eventMap[i] == "button":
+               elif eventList[i] == "button":
                        #Write two events subsequently
                        extractedEvents.write("\t\t\tdef event = Verify.getInt(0,1)\n")
                        extractedEvents.write("\t\t\tif (event == 0) {\n")
@@ -161,7 +195,7 @@ def ExtractEvents(extractedEvents):
                                extractedEvents.write("\t\t" + line)
                        event.close()
                        extractedEvents.write("\t\t\t}\n")
-               elif eventMap[i] == "presence":
+               elif eventList[i] == "presence":
                        #Write two events subsequently
                        extractedEvents.write("\t\t\tdef event = Verify.getInt(0,1)\n")
                        extractedEvents.write("\t\t\tif (event == 0) {\n")
@@ -175,7 +209,7 @@ def ExtractEvents(extractedEvents):
                                extractedEvents.write("\t\t" + line)
                        event.close()
                        extractedEvents.write("\t\t\t}\n")
-               elif eventMap[i] == "doorState":
+               elif eventList[i] == "doorState":
                        #Write two events subsequently
                        extractedEvents.write("\t\t\tdef event = Verify.getInt(0,1)\n")
                        extractedEvents.write("\t\t\tif (event == 0) {\n")
@@ -189,7 +223,7 @@ def ExtractEvents(extractedEvents):
                                extractedEvents.write("\t\t" + line)
                        event.close()
                        extractedEvents.write("\t\t\t}\n")
-               elif eventMap[i] == "motion":
+               elif eventList[i] == "motion":
                        #Write two events subsequently
                        extractedEvents.write("\t\t\tdef event = Verify.getInt(0,1)\n")
                        extractedEvents.write("\t\t\tif (event == 0) {\n")
@@ -203,7 +237,7 @@ def ExtractEvents(extractedEvents):
                                extractedEvents.write("\t\t" + line)
                        event.close()
                        extractedEvents.write("\t\t\t}\n")
-               elif eventMap[i] == "smoke":
+               elif eventList[i] == "smoke":
                        #Write three events subsequently
                        extractedEvents.write("\t\t\tdef event = Verify.getInt(0,2)\n")
                        extractedEvents.write("\t\t\tif (event == 0) {\n")
@@ -222,31 +256,44 @@ def ExtractEvents(extractedEvents):
                                extractedEvents.write("\t\t" + line)
                        event.close()
                        extractedEvents.write("\t\t\t}\n")
-               elif eventMap[i] == "carbonMonoxide":
+               elif eventList[i] == "carbonMonoxide":
+                       #Check which capability
+                       variable = eventVarMap[eventList[i]]
+                       capability = capabilityMap[variable]
+       
                        #Write three events subsequently
                        extractedEvents.write("\t\t\tdef event = Verify.getInt(0,2)\n")
-                       extractedEvents.write("\t\t\tif (event == 0) {\n")
-                       event = open("eventSimulator/carbonMonoxideClearEvent.groovy", "r")                     
+                       extractedEvents.write("\t\t\tif (event == 0) {\n")                      
+                       if capability == "capability.smokeDetector":
+                               event = open("eventSimulator/smokeCarbonMonoxideClearEvent.groovy", "r")
+                       elif capability == "capability.carbonMonoxideDetector":
+                               event = open("eventSimulator/carbonMonoxideClearEvent.groovy", "r")
                        for line in event:
                                extractedEvents.write("\t\t" + line)
                        event.close()
                        extractedEvents.write("\t\t\t} else if (event == 1) {\n")
-                       event = open("eventSimulator/carbonMonoxideDetectedEvent.groovy", "r")
+                       if capability == "capability.smokeDetector":
+                               event = open("eventSimulator/smokeCarbonMonoxideDetectedEvent.groovy", "r")
+                       elif capability == "capability.carbonMonoxideDetector":
+                               event = open("eventSimulator/carbonMonoxideDetectedEvent.groovy", "r")
                        for line in event:
                                extractedEvents.write("\t\t" + line)
                        event.close()
                        extractedEvents.write("\t\t\t} else {\n")
-                       event = open("eventSimulator/carbonMonoxideTestedEvent.groovy", "r")
+                       if capability == "capability.smokeDetector":
+                               event = open("eventSimulator/smokeCarbonMonoxideTestedEvent.groovy", "r")
+                       elif capability == "capability.carbonMonoxideDetector":
+                               event = open("eventSimulator/carbonMonoxideTestedEvent.groovy", "r")
                        for line in event:
                                extractedEvents.write("\t\t" + line)
                        event.close()
                        extractedEvents.write("\t\t\t}\n")
-               elif eventMap[i] == "battery":
+               elif eventList[i] == "battery":
                        event = open("eventSimulator/batteryChargeEvent.groovy", "r")
                        for line in event:
                                extractedEvents.write(line)
                        event.close()
-               elif eventMap[i] == "thermostatMode":
+               elif eventList[i] == "thermostatMode":
                        #Write five events subsequently
                        extractedEvents.write("\t\t\tdef event = Verify.getInt(0,4)\n")
                        extractedEvents.write("\t\t\tif (event == 0) {\n")
@@ -275,7 +322,7 @@ def ExtractEvents(extractedEvents):
                                extractedEvents.write("\t\t" + line)
                        event.close()
                        extractedEvents.write("\t\t\t}\n")
-               elif eventMap[i] == "switch":
+               elif eventList[i] == "switch":
                        #Write two events subsequently
                        extractedEvents.write("\t\t\tdef event = Verify.getInt(0,1)\n")
                        extractedEvents.write("\t\t\tif (event == 0) {\n")
@@ -289,7 +336,7 @@ def ExtractEvents(extractedEvents):
                                extractedEvents.write("\t\t" + line)
                        event.close()
                        extractedEvents.write("\t\t\t}\n")
-               elif eventMap[i] == "location": #Case for Location event
+               elif eventList[i] == "location": #Case for Location event
                        #Write three events subsequently
                        extractedEvents.write("\t\t\tdef event = Verify.getInt(0,2)\n")
                        extractedEvents.write("\t\t\tif (event == 0) {\n")
@@ -308,12 +355,64 @@ def ExtractEvents(extractedEvents):
                                extractedEvents.write("\t\t" + line)
                        event.close()
                        extractedEvents.write("\t\t\t}\n")
+               elif eventList[i] == "acceleration":
+                       #Write two events subsequently
+                       extractedEvents.write("\t\t\tdef event = Verify.getInt(0,1)\n")
+                       extractedEvents.write("\t\t\tif (event == 0) {\n")
+                       event = open("eventSimulator/accelerationActiveEvent.groovy", "r")                      
+                       for line in event:
+                               extractedEvents.write("\t\t" + line)
+                       event.close()
+                       extractedEvents.write("\t\t\t} else {\n")
+                       event = open("eventSimulator/accelerationInactiveEvent.groovy", "r")
+                       for line in event:
+                               extractedEvents.write("\t\t" + line)
+                       event.close()
+                       extractedEvents.write("\t\t\t}\n")
+               elif eventList[i] == "beacon":
+                       #Write two events subsequently
+                       extractedEvents.write("\t\t\tdef event = Verify.getInt(0,1)\n")
+                       extractedEvents.write("\t\t\tif (event == 0) {\n")
+                       event = open("eventSimulator/beaconPresenceEvent.groovy", "r")                  
+                       for line in event:
+                               extractedEvents.write("\t\t" + line)
+                       event.close()
+                       extractedEvents.write("\t\t\t} else {\n")
+                       event = open("eventSimulator/beaconLeftEvent.groovy", "r")
+                       for line in event:
+                               extractedEvents.write("\t\t" + line)
+                       event.close()
+                       extractedEvents.write("\t\t\t}\n")
+               elif eventList[i] == "color":
+                       event = open("eventSimulator/colorChangeEvent.groovy", "r")
+                       for line in event:
+                               extractedEvents.write(line)
+                       event.close()
+               elif eventList[i] == "hue":
+                       event = open("eventSimulator/hueChangeEvent.groovy", "r")
+                       for line in event:
+                               extractedEvents.write(line)
+                       event.close()
+               elif eventList[i] == "saturation":
+                       event = open("eventSimulator/saturationChangeEvent.groovy", "r")
+                       for line in event:
+                               extractedEvents.write(line)
+                       event.close()
 
                ###TODO: Add more events later
                extractedEvents.write("\t\t\tbreak\n")
        extractedEvents.write("\t}\n")
-       #extractedEvents.write("\tcounter--\n")
        extractedEvents.write("}\n")
+       
+def CheckIfOnlyTouchEvents():
+       #Check and throw an error if it is all touch events
+       #This is called Direct-Direct interaction and we do not model-check for this case
+       onlyTouchEvents = True
+       for item in eventList:
+               if item != "nfcTouch" and item != "app":
+                       onlyTouchEvents = False
+       if onlyTouchEvents is True and app1Subscribe is True and app2Subscribe is True:
+               raise Exception("\n\nDirect-Direct Interaction detected: we are skipping this pair...\n\n")
                
 #Extract objects to call functions from App1
 F1 = open("Extractor/App1/App1.groovy", "r")
@@ -329,6 +428,7 @@ F2.close()
 
 #Prepare eventSimulator file while parsing the App1 and App2 files
 extractedEvents = open("eventSimulator/eventSimulator.groovy", "w+")
+CheckIfOnlyTouchEvents()
 ExtractEvents(extractedEvents)
 extractedEvents.close()
 
@@ -350,7 +450,7 @@ extractorFile.close()
 Extractor.close()
 F1.close()
 #Run the file to extract the objects
-os.system("groovy Extractor/extractorFile.groovy")
+os.system("groovy -classpath lib/jpf.jar Extractor/extractorFile.groovy")
 
 
 #Save the extracted methods and app2 in a same file to extract information
@@ -371,7 +471,7 @@ for line in F2:
 extractorFile.close()
 Extractor.close()
 F2.close()
-os.system("groovy Extractor/extractorFile.groovy")
+os.system("groovy -classpath lib/jpf.jar Extractor/extractorFile.groovy")