Fixing a bug in ExtractorScript.py: consuming too many tokens.
[smartthings-infrastructure.git] / Extractor / extractorFile.groovy
1 ////////////////////
2 @Field App
3 App = "App2"
4 ////////////////////////////////////////
5 //import libraries
6 import groovy.transform.Field
7
8
9 //import classes
10 //Importing Classes
11 import ContactSensor.ContactSensor
12 import ContactSensor.ContactSensors
13 import DoorControl.DoorControl
14 import DoorControl.DoorControls
15 import Lock.Lock
16 import Lock.Locks
17 import Thermostat.Thermostat
18 import Thermostat.Thermostats
19 import Switch.Switch
20 import Switch.Switches
21 import PresenceSensor.PresenceSensor
22 import PresenceSensor.PresenceSensors
23 import Logger.Logger
24 import Location.LocationVar
25 import Location.Phrase
26 import appTouch.Touched
27 import NfcTouch.NfcTouch
28 import AeonKeyFob.AeonKeyFob
29 import AeonKeyFob.AeonKeyFobs
30 import MusicPlayer.MusicPlayer
31 import MusicPlayer.MusicPlayers
32 import Timer.SimulatedTimer
33
34 //GlobalVariables
35 @Field def location = new LocationVar()
36 //Settings variable defined to settings on purpose
37 @Field def settings = [app: "app"]
38 //Global variable for state[mode]
39 @Field def state = [home:[],away:[],night:[]]
40 //Create a global logger object for methods
41 @Field def log = new Logger()
42
43
44 //Global variables for files
45 @Field File extractedObjectsApp1 = new File("Extractor/App1/extractedObjectsApp1.groovy")
46 @Field File extractedObjectsApp2 = new File("Extractor/App2/extractedObjectsApp2.groovy")
47 @Field File extractedObjectsConstructorApp1 = new File("Extractor/App1/extractedObjectsConstructorApp1.groovy")
48 @Field File extractedObjectsConstructorApp2 = new File("Extractor/App2/extractedObjectsConstructorApp2.groovy")
49
50
51 //Empty the files
52 if (App == "App1") {
53         extractedObjectsApp1.write("")
54         extractedObjectsConstructorApp1.write("")
55 } else if (App == "App2") {
56         extractedObjectsApp2.write("")
57         extractedObjectsConstructorApp2.write("")
58 }
59
60
61
62
63
64 //Global objects
65 //Global Object for class Touch Sensor!
66 @Field touchSensorObjects = 0
67 @Field def touchSensorObject0
68 @Field def touchSensorObject1
69 @Field def touchSensorObject2
70 //Global Object for class switch!
71 @Field switchObjects = 0
72 @Field def switchObject0
73 @Field def switchObject1
74 @Field def switchObject2
75 //Global Object for class lock!
76 @Field lockObjects = 0
77 @Field def lockObject0
78 @Field def lockObject1
79 @Field def lockObject2
80 //Global Object for class door control!
81 @Field doorControlObjects = 0
82 @Field def doorControlObject0
83 @Field def doorControlObject1
84 @Field def doorControlObject2
85 //Global Object for class contact sensor!
86 @Field contactObjects = 0
87 @Field def contactObject0
88 @Field def contactObject1
89 @Field def contactObject2
90 //Global Object for class presence sensor!
91 @Field presenceSensorObjects = 0
92 @Field def presenceSensorObject0
93 @Field def presenceSensorObject1
94 @Field def presenceSensorObject2
95 //Global Object for class thermostat!
96 @Field thermostatObjects = 0
97 @Field def thermostatObject0
98 @Field def thermostatObject1
99 @Field def thermostatObject2
100 //Global Object for class music player!
101 @Field musicPlayerObjects = 0
102 @Field def musicPlayerObject0
103 @Field def musicPlayerObject1
104 @Field def musicPlayerObject2
105 //Global Object for class music player!
106 @Field aeonKeyFobObjects = 0
107 @Field def aeonKeyFobObject0
108 @Field def aeonKeyFobObject1
109 @Field def aeonKeyFobObject2
110
111
112 //Global variables
113 //For mode
114 @Field modeVariables = 0
115 @Field mode0
116 @Field mode1
117 @Field mode2
118 @Field mode3
119 @Field mode4
120 @Field mode5
121 //For number
122 @Field numberVariables = 0
123 @Field number0
124 @Field number1
125 @Field number2
126 @Field number3
127 @Field number4
128 @Field number5
129 //For time
130 @Field timeVariables = 0
131 @Field time0
132 @Field time1
133 @Field time2
134 @Field time3
135 @Field time4
136 @Field time5
137 //For enum
138 @Field enumVariables = 0
139 @Field enum0
140 @Field enum1
141 @Field enum2
142 @Field enum3
143 @Field enum4
144 @Field enum5
145 //For phone
146 @Field phoneVariables = 0
147 @Field phone0
148 @Field phone1
149 @Field phone2
150 @Field phone3
151 @Field phone4
152 @Field phone5
153 //For contact
154 @Field contactVariables = 0
155 @Field contact0
156 @Field contact1
157 @Field contact2
158 @Field contact3
159 @Field contact4
160 @Field contact5
161
162
163
164 /////Input Methods/////
165 //input "",""
166 def input(String name, String type) {
167         LinkedHashMap metaData = []
168         metaData.put('name',name)
169         metaData.put('type',type)
170         input(metaData)
171 }
172
173 //input "","",linkedHashMap
174 def input(LinkedHashMap metaData, String name, String type) {
175         metaData.put('name',name)
176         metaData.put('type',type)
177         input(metaData)
178 }
179
180 //input linkedHashMap
181 def input(LinkedHashMap metaData) {
182         if (metaData.containsKey('title')) {
183                 println metaData['title']
184         }
185         if (metaData.containsKey('options')) {
186                 println "Options: "+metaData['options']
187         }
188         switch(metaData['type']) {
189                 case "capability.lock":
190                         if (lockObjects == 0) {
191                                 lockObject0 = metaData['name']
192                                 this[lockObject0] = new Locks({}, 1)
193                         } else if (lockObjects == 1) {
194                                 lockObject1 = metaData['name']
195                                 this[lockObject1] = new Locks({}, 1)
196                         } else if (lockObjects == 2) {
197                                 lockObject2 = metaData['name']
198                                 this[lockObject2] = new Locks({}, 1)
199                         }
200
201                         lockObjects=lockObjects+1
202
203                         settings.put(metaData['name'], metaData['name']) 
204
205                         if (App == "App1") {
206                                 extractedObjectsApp1.append("//Object for class lock!\n")
207                                 extractedObjectsApp1.append("def "+metaData['name']+"\n")
208                                 extractedObjectsConstructorApp1.append(metaData['name']+" = obj.lockObject\n")          
209                         } else {
210                                 extractedObjectsApp2.append("//Object for class lock!\n")
211                                 extractedObjectsApp2.append("def "+metaData['name']+"\n")
212                                 extractedObjectsConstructorApp2.append(metaData['name']+" = obj.lockObject\n")
213                         }
214                         break
215                 case "capability.alarm":
216                         break
217                 case "capability.battery":
218                         break
219                 case "capability.beacon":
220                         break
221                 case "capability.carbonMonoxideDetector":
222                         break
223                 case "capability.colorControl":
224                         break
225                 case "capability.contactSensor":
226                         if (contactObjects == 0) {
227                                 contactObject0 = metaData['name']
228                                 this[contactObject0] = new ContactSensors({}, 1)
229                         } else if (contactObjects == 1) {
230                                 contactObject1 = metaData['name']
231                                 this[contactObject1] = new ContactSensors({}, 1)
232                         } else if (contactObjects == 2) {
233                                 contactObject2 = metaData['name']
234                                 this[contactObject2] = new ContactSensors({}, 1)
235                         }
236
237                         contactObjects=contactObjects+1
238
239                         settings.put(metaData['name'], metaData['name'])
240
241                         if (App == "App1") {
242                                 extractedObjectsApp1.append("//Object for class contactSensor!\n")
243                                 extractedObjectsApp1.append("def "+metaData['name']+"\n")
244                                 extractedObjectsConstructorApp1.append(metaData['name']+" = obj.contactObject\n")               
245                         } else {
246                                 extractedObjectsApp2.append("//Object for class contactSensor!\n")
247                                 extractedObjectsApp2.append("def "+metaData['name']+"\n")
248                                 extractedObjectsConstructorApp2.append(metaData['name']+" = obj.contactObject\n")
249                         }
250                         break
251                 case "capability.doorControl":
252                         if (doorControlObjects == 0) {
253                                 doorControlObject0 = metaData['name']
254                                 this[doorControlObject0] = new DoorControls({}, 1)
255                         } else if (doorControlObjects == 1) {
256                                 doorControlObject1 = metaData['name']
257                                 this[doorControlObject1] = new DoorControls({}, 1)
258                         } else if (doorControlObjects == 2) {
259                                 doorControlObject2 = metaData['name']
260                                 this[doorControlObject2] = new DoorControls({}, 1)
261                         }
262
263                         doorControlObjects=doorControlObjects+1
264
265                         settings.put(metaData['name'], metaData['name'])
266
267                         if (App == "App1") {
268                                 extractedObjectsApp1.append("//Object for class door control!\n")
269                                 extractedObjectsApp1.append("def "+metaData['name']+"\n")
270                                 extractedObjectsConstructorApp1.append(metaData['name']+" = obj.doorControlObject\n")           
271                         } else {
272                                 extractedObjectsApp2.append("//Object for class door control!\n")
273                                 extractedObjectsApp2.append("def "+metaData['name']+"\n")
274                                 extractedObjectsConstructorApp2.append(metaData['name']+" = obj.doorControlObject\n")
275                         }
276                         break
277                 case "capability.energyMeter":
278                         break
279                 case "capability.illuminanceMeasurement":
280                         break
281                 case "capability.accelerationSensor":
282                         break
283                 case "capability.motionSensor":
284                         break
285                 case "capability.musicPlayer":
286                         if (musicPlayerObjects == 0) {
287                                 musicPlayerObject0 = metaData['name']
288                                 this[musicPlayerObject0] = new MusicPlayers({}, 1)
289                         } else if (musicPlayerObjects == 1) {
290                                 musicPlayerObject1 = metaData['name']
291                                 this[musicPlayerObject1] = new MusicPlayers({}, 1)
292                         } else if (musicPlayerObjects == 2) {
293                                 musicPlayerObject2 = metaData['name']
294                                 this[musicPlayerObject2] = new MusicPlayers({}, 1)
295                         }
296
297                         musicPlayerObjects=musicPlayerObjects+1
298
299                         settings.put(metaData['name'], metaData['name']) 
300
301                         if (App == "App1") {
302                                 extractedObjectsApp1.append("//Object for class music player!\n")
303                                 extractedObjectsApp1.append("def "+metaData['name']+"\n")
304                                 extractedObjectsConstructorApp1.append(metaData['name']+" = obj.musicPlayerObject\n")           
305                         } else {
306                                 extractedObjectsApp2.append("//Object for class music player!\n")
307                                 extractedObjectsApp2.append("def "+metaData['name']+"\n")
308                                 extractedObjectsConstructorApp2.append(metaData['name']+" = obj.musicPlayerObject\n")
309                         }
310                         break
311                 case "capability.powerMeter":
312                         break
313                 case "capability.presenceSensor":
314                         if (presenceSensorObjects == 0) {
315                                 presenceSensorObject0 = metaData['name']
316                                 this[presenceSensorObject0] = new PresenceSensors({}, 1)
317                         } else if (presenceSensorObjects == 1) {
318                                 presenceSensorObject1 = metaData['name']
319                                 this[presenceSensorObject1] = new PresenceSensors({}, 1)
320                         } else if (presenceSensorObjects == 2) {
321                                 presenceSensorObject2 = metaData['name']
322                                 this[presenceSensorObject2] = new PresenceSensors({}, 1)
323                         }
324
325                         presenceSensorObjects=presenceSensorObjects+1
326
327                         settings.put(metaData['name'], metaData['name'])
328
329                         if (App == "App1") {
330                                 extractedObjectsApp1.append("//Object for class presence sensor!\n")
331                                 extractedObjectsApp1.append("def "+metaData['name']+"\n")
332                                 extractedObjectsConstructorApp1.append(metaData['name']+" = obj.presenceSensorObject\n")                
333                         } else {
334                                 extractedObjectsApp2.append("//Object for class presence sensor!\n")
335                                 extractedObjectsApp2.append("def "+metaData['name']+"\n")
336                                 extractedObjectsConstructorApp2.append(metaData['name']+" = obj.presenceSensorObject\n")
337                         }
338                         break
339                 case "capability.relativeHumidityMeasurement":
340                         break
341                 case "capability.relaySwitch":
342                         break
343                 case "capability.sleepSensor":
344                         break
345                 case "capability.smokeDetector":
346                         break
347                 case "capability.stepSensor":
348                         break
349                 case "capability.switch":
350                         if (switchObjects == 0) {
351                                 switchObject0 = metaData['name']
352                                 this[switchObject0] = new Switches({}, 1)
353                         } else if (switchObjects == 1) {
354                                 switchObject1 = metaData['name']
355                                 this[switchObject1] = new Switches({}, 1)
356                         } else if (switchObjects == 2) {
357                                 switchObject2 = metaData['name']
358                                 this[switchObject2] = new Switches({}, 1)
359                         }
360
361                         switchObjects=switchObjects+1
362                         
363                         settings.put(metaData['name'], metaData['name'])
364
365                         if (App == "App1") {
366                                 extractedObjectsApp1.append("//Object for class switch!\n")
367                                 extractedObjectsApp1.append("def "+metaData['name']+"\n")
368                                 extractedObjectsConstructorApp1.append(metaData['name']+" = obj.switchObject\n")                
369                         } else {
370                                 extractedObjectsApp2.append("//Object for class switch!\n")
371                                 extractedObjectsApp2.append("def "+metaData['name']+"\n")
372                                 extractedObjectsConstructorApp2.append(metaData['name']+" = obj.switchObject\n")
373                         }
374                         break
375                 case "capability.switchLevel":
376                         break
377                 case "capability.temperatureMeasurement":
378                         break
379                 case "capability.thermostat":
380                         if (thermostatObjects == 0) {
381                                 thermostatObject0 = metaData['name']
382                                 this[thermostatObject0] = new Thermostats({}, 1)
383                         } else if (thermostatObjects == 1) {
384                                 thermostatObject1 = metaData['name']
385                                 this[thermostatObject1] = new Thermostats({}, 1)
386                         } else if (thermostatObjects == 2) {
387                                 thermostatObject2 = metaData['name']
388                                 this[thermostatObject2] = new Thermostats({}, 1)
389                         }
390
391                         thermostatObjects=thermostatObjects+1
392
393                         settings.put(metaData['name'], metaData['name'])
394
395                         if (App == "App1") {
396                                 extractedObjectsApp1.append("//Object for class thermostat!\n")
397                                 extractedObjectsApp1.append("def "+metaData['name']+"\n")
398                                 extractedObjectsConstructorApp1.append(metaData['name']+" = obj.thermostatObject\n")            
399                         } else {
400                                 extractedObjectsApp2.append("//Object for class thermostat!\n")
401                                 extractedObjectsApp2.append("def "+metaData['name']+"\n")
402                                 extractedObjectsConstructorApp2.append(metaData['name']+" = obj.thermostatObject\n")
403                         }
404                         break
405                 case "capability.valve":
406                         break
407                 case "capability.waterSensor":
408                         break
409                 case "capability.touchSensor":
410                         if (touchSensorObjects == 0) {
411                                 touchSensorObject0 = metaData['name']
412                                 this[touchSensorObject0] = new NfcTouch({}, 1)
413                         } else if (touchSensorObjects == 1) {
414                                 touchSensorObject1 = metaData['name']
415                                 this[touchSensorObject1] = new NfcTouch({}, 1)
416                         } else if (touchSensorObjects == 2) {
417                                 touchSensorObject2 = metaData['name']
418                                 this[touchSensorObject2] = new NfcTouch({}, 1)
419                         }
420
421                         touchSensorObjects=touchSensorObjects+1
422
423                         settings.put(metaData['name'], metaData['name'])
424
425                         if (App == "App1") {
426                                 extractedObjectsApp1.append("//Object for class Touch Sensor!\n")
427                                 extractedObjectsApp1.append("def "+metaData['name']+"\n")
428                                 extractedObjectsConstructorApp1.append(metaData['name']+" = obj.touchSensorObject\n")           
429                         } else {
430                                 extractedObjectsApp2.append("//Object for class Touch Sensor!\n")
431                                 extractedObjectsApp2.append("def "+metaData['name']+"\n")
432                                 extractedObjectsConstructorApp2.append(metaData['name']+" = obj.touchSensorObject\n")
433                         }
434                         break
435                 case "capability.imageCapture":
436                         break
437                 case "device.mobilePresence":
438                         break
439                 case "device.aeonKeyFob":
440                         if (aeonKeyFobObjects == 0) {
441                                 aeonKeyFobObject0 = metaData['name']
442                                 this[aeonKeyFobObject0] = new AeonKeyFobs({}, 1)
443                         } else if (aeonKeyFobObjects == 1) {
444                                 aeonKeyFobObject1 = metaData['name']
445                                 this[aeonKeyFobObject1] = new AeonKeyFobs({}, 1)
446                         } else if (aeonKeyFobObjects == 2) {
447                                 aeonKeyFobObject2 = metaData['name']
448                                 this[aeonKeyFobObject2] = new AeonKeyFobs({}, 1)
449                         }
450
451                         aeonKeyFobObjects=aeonKeyFobObjects+1
452
453                         settings.put(metaData['name'], metaData['name']) 
454
455                         if (App == "App1") {
456                                 extractedObjectsApp1.append("//Object for class aeon key fob!\n")
457                                 extractedObjectsApp1.append("def "+metaData['name']+"\n")
458                                 extractedObjectsConstructorApp1.append(metaData['name']+" = obj.aeonKeyFobObject\n")            
459                         } else {
460                                 extractedObjectsApp2.append("//Object for class aeon key fob!\n")
461                                 extractedObjectsApp2.append("def "+metaData['name']+"\n")
462                                 extractedObjectsConstructorApp2.append(metaData['name']+" = obj.aeonKeyFobObject\n")
463                         }
464                         break
465                 case "mode":
466                         def userInput = System.console().readLine 'Enter the mode:'
467
468                         if (modeVariables == 0) {
469                                 mode0 = metaData['name']
470                                 this[mode0] = userInput
471                         } else if (modeVariables == 1) {
472                                 mode1 = metaData['name']
473                                 this[mode1] = userInput
474                         } else if (modeVariables == 2) {
475                                 mode2 = metaData['name']
476                                 this[mode2] = userInput
477                         } else if (modeVariables == 3) {
478                                 mode3 = metaData['name']
479                                 this[mode3] = userInput
480                         } else if (modeVariables == 4) {
481                                 mode4 = metaData['name']
482                                 this[mode4] = userInput
483                         } else if (modeVariables == 5) {
484                                 mode5 = metaData['name']
485                                 this[mode5] = userInput
486                         }
487
488                         modeVariables=modeVariables+1
489
490                         settings.put(metaData['name'], metaData['name'])
491
492                         if (App == "App1") {                    
493                                 extractedObjectsApp1.append("//Global variable for mode!\n")
494                                 extractedObjectsApp1.append("def "+metaData['name']+" = \""+userInput+"\"\n")
495                         } else {
496                                 extractedObjectsApp2.append("//Global variable for mode!\n")
497                                 extractedObjectsApp2.append("def "+metaData['name']+" = \""+userInput+"\"\n")
498                         }
499                         break
500                 case "decimal":
501                         break
502                 case "text":
503                         break
504                 case "number":
505                         def userInput = System.console().readLine 'Enter the number:'
506                         
507                         if (numberVariables == 0) {
508                                 number0 = metaData['name']
509                                 this[number0] = userInput
510                         } else if (numberVariables == 1) {
511                                 number1 = metaData['name']
512                                 this[number1] = userInput
513                         } else if (numberVariables == 2) {
514                                 number2 = metaData['name']
515                                 this[number2] = userInput
516                         } else if (numberVariables == 3) {
517                                 number3 = metaData['name']
518                                 this[number3] = userInput
519                         } else if (numberVariables == 4) {
520                                 number4 = metaData['name']
521                                 this[number4] = userInput
522                         } else if (numberVariables == 5) {
523                                 number5 = metaData['name']
524                                 this[number5] = userInput
525                         }
526
527                         numberVariables=numberVariables+1
528
529                         settings.put(metaData['name'], metaData['name'])
530
531                         if (App == "App1") {                    
532                                 extractedObjectsApp1.append("//Global variable for number!\n")
533                                 extractedObjectsApp1.append("def "+metaData['name']+" = "+userInput+"\n")
534                         } else {
535                                 extractedObjectsApp2.append("//Global variable for number!\n")
536                                 extractedObjectsApp2.append("def "+metaData['name']+" = "+userInput+"\n")
537                         }
538                         break
539                 case "time":
540                         def userInput = System.console().readLine 'Enter the time:'
541                         
542                         if (timeVariables == 0) {
543                                 time0 = metaData['name']
544                                 this[time0] = userInput
545                         } else if (timeVariables == 1) {
546                                 time1 = metaData['name']
547                                 this[time1] = userInput
548                         } else if (timeVariables == 2) {
549                                 time2 = metaData['name']
550                                 this[time2] = userInput
551                         } else if (timeVariables == 3) {
552                                 time3 = metaData['name']
553                                 this[time3] = userInput
554                         } else if (timeVariables == 4) {
555                                 time4 = metaData['name']
556                                 this[time4] = userInput
557                         } else if (timeVariables == 5) {
558                                 time5 = metaData['name']
559                                 this[time5] = userInput
560                         }
561
562                         timeVariables=timeVariables+1
563
564                         settings.put(metaData['name'], metaData['name'])
565
566                         if (App == "App1") {                    
567                                 extractedObjectsApp1.append("//Global variable for time!\n")
568                                 extractedObjectsApp1.append("def "+metaData['name']+" = \""+userInput+"\"\n")
569                         } else {
570                                 extractedObjectsApp2.append("//Global variable for time!\n")
571                                 extractedObjectsApp2.append("def "+metaData['name']+" = \""+userInput+"\"\n")
572                         }
573                         break
574                 case "enum":
575                         def userInput = System.console().readLine 'Enter the enum:'
576         
577                         if (enumVariables == 0) {
578                                 enum0 = metaData['name']
579                                 this[enum0] = userInput
580                         } else if (enumVariables == 1) {
581                                 enum1 = metaData['name']
582                                 this[enum1] = userInput
583                         } else if (enumVariables == 2) {
584                                 enum2 = metaData['name']
585                                 this[enum2] = userInput
586                         } else if (enumVariables == 3) {
587                                 enum3 = metaData['name']
588                                 this[enum3] = userInput
589                         } else if (enumVariables == 4) {
590                                 enum4 = metaData['name']
591                                 this[enum4] = userInput
592                         } else if (enumVariables == 5) {
593                                 enum5 = metaData['name']
594                                 this[enum5] = userInput
595                         }
596
597                         enumVariables=enumVariables+1
598
599                         settings.put(metaData['name'], metaData['name'])
600
601                         if (App == "App1") {                    
602                                 extractedObjectsApp1.append("//Global variable for enum!\n")
603                                 extractedObjectsApp1.append("def "+metaData['name']+" = \""+userInput+"\"\n")
604                         } else {
605                                 extractedObjectsApp2.append("//Global variable for enum!\n")
606                                 extractedObjectsApp2.append("def "+metaData['name']+" = \""+userInput+"\"\n")
607                         }
608                         break
609                 case "bool":
610                         break
611                 case "phone":
612                         def userInput = System.console().readLine 'Enter the phone:'
613
614                         if (phoneVariables == 0) {
615                                 phone0 = metaData['name']
616                                 this[phone0] = userInput
617                         } else if (phoneVariables == 1) {
618                                 phone1 = metaData['name']
619                                 this[phone1] = userInput
620                         } else if (phoneVariables == 2) {
621                                 phone2 = metaData['name']
622                                 this[phone2] = userInput
623                         } else if (phoneVariables == 3) {
624                                 phone3 = metaData['name']
625                                 this[phone3] = userInput
626                         } else if (phoneVariables == 4) {
627                                 phone4 = metaData['name']
628                                 this[phone4] = userInput
629                         } else if (phoneVariables == 5) {
630                                 phone5 = metaData['name']
631                                 this[phone5] = userInput
632                         }
633
634                         phoneVariables=phoneVariables+1
635
636                         settings.put(metaData['name'], metaData['name'])
637
638                         if (App == "App1") {                    
639                                 extractedObjectsApp1.append("//Global variable for phone!\n")
640                                 extractedObjectsApp1.append("def "+metaData['name']+" = "+userInput+"\n")
641                         } else {
642                                 extractedObjectsApp2.append("//Global variable for phone!\n")
643                                 extractedObjectsApp2.append("def "+metaData['name']+" = "+userInput+"\n")
644                         }
645                         break
646                 case "contact":
647                         def userInput = System.console().readLine 'Enter the metaData['name'] of the contact:'
648         
649                         if (contactVariables == 0) {
650                                 contact0 = metaData['name']
651                                 this[contact0] = userInput
652                         } else if (contactVariables == 1) {
653                                 contact1 = metaData['name']
654                                 this[contact1] = userInput
655                         } else if (contactVariables == 2) {
656                                 contact2 = metaData['name']
657                                 this[contact2] = userInput
658                         } else if (contactVariables == 3) {
659                                 contact3 = metaData['name']
660                                 this[contact3] = userInput
661                         } else if (contactVariables == 4) {
662                                 contact4 = metaData['name']
663                                 this[contact4] = userInput
664                         } else if (contactVariables == 5) {
665                                 contact5 = metaData['name']
666                                 this[contact5] = userInput
667                         }
668
669                         contactVariables=contactVariables+1
670
671                         settings.put(metaData['name'], metaData['name'])
672
673                         if (App == "App1") {                    
674                                 extractedObjectsApp1.append("//Global variable for contact!\n")
675                                 extractedObjectsApp1.append("def "+metaData['name']+" = \""+userInput+"\"\n")
676                         } else {
677                                 extractedObjectsApp2.append("//Global variable for contact!\n")
678                                 extractedObjectsApp2.append("def "+metaData['name']+" = \""+userInput+"\"\n")
679                         }
680                         break
681                 default:
682                         break
683         }
684 }
685
686 def label(LinkedHashMap metaData) {
687         if (metaData.containsKey('title')) {
688                 println metaData['title']
689         }
690         if (metaData.containsKey('options')) {
691                 println "Options: "+metaData['options']
692         }
693
694         println("//IGNORE--ForMobileUse//")
695 }
696
697 def mode(LinkedHashMap metaData) {
698         if (metaData.containsKey('title')) {
699                 println metaData['title']
700         }
701         if (metaData.containsKey('options')) {
702                 println "Options: "+metaData['options']
703         }
704
705         println("//IGNORE--ForMobileUse//")
706 }
707 /////Input Methods/////
708
709
710 /////MethodsForExtraction/////
711 def definition(LinkedHashMap metaData) {
712         println("///Just some information///")
713 }
714
715 def preferences(Closure inputData) {
716         find(inputData) //Run the closure to extract pages/sections/inputMethods
717         if (App == "App1") {                    
718                 extractedObjectsConstructorApp1.append("//Global variable for settings!\n")
719                 extractedObjectsConstructorApp1.append("settings = $settings\n")
720         } else {
721                 extractedObjectsConstructorApp2.append("//Global variable for settings!\n")
722                 extractedObjectsConstructorApp2.append("settings = $settings\n")
723         }
724 }
725
726 def page(LinkedHashMap metaData, Closure inputData) {
727         if (metaData.containsKey('name'))
728                 println(metaData['name'])
729         if (metaData.containsKey('title'))
730                 println(metaData['title'])
731
732         find(inputData) //Run the closure to extract sections/inputMethods
733 }
734
735 def page(LinkedHashMap metaData) {
736         def nameOfFunction = metaData['name']
737         "$nameOfFunction"() //Call the page     
738 }
739
740 def dynamicPage(LinkedHashMap metaData, Closure inputData) {
741         if (metaData.containsKey('name'))
742                 println(metaData['name'])
743         if (metaData.containsKey('title'))
744                 println(metaData['title'])
745
746         find(inputData) //Run the closure to extract sections/inputMethods
747 }
748
749 def section(String title, Closure inputData) {
750         println(title)
751         find(inputData) //Run the closure to extract inputMethods
752 }
753
754 def section(Closure inputData) {
755         find(inputData) //Run the closure to extract inputMethods
756 }
757
758 def section(LinkedHashMap metaData, Closure inputData) {
759         find(inputData) //Run the closure to extract inputMethods
760 }
761 /////MethodsForExtraction/////
762
763
764
765 ////////////////
766 definition(
767     name: "NFC Tag Toggle",
768     namespace: "smartthings",
769     author: "SmartThings",
770     description: "Allows toggling of a switch, lock, or garage door based on an NFC Tag touch event",
771     category: "SmartThings Internal",
772     iconUrl: "https://s3.amazonaws.com/smartapp-icons/Developers/nfc-tag-executor.png",
773     iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Developers/nfc-tag-executor@2x.png",
774     iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Developers/nfc-tag-executor@2x.png")
775
776
777 preferences {
778     page(name: "pageOne", title: "Device selection", uninstall: true, nextPage: "pageTwo") {
779         section("Select an NFC tag") {
780             input "tag", "capability.touchSensor", title: "NFC Tag"
781         }
782         section("Select devices to control") {
783             input "switch1", "capability.switch", title: "Light or switch", required: false, multiple: true
784             input "lock", "capability.lock", title: "Lock", required: false, multiple: true
785             input "garageDoor", "capability.doorControl", title: "Garage door controller", required: false, multiple: true
786         }
787     }
788
789     page(name: "pageTwo", title: "Master devices", install: true, uninstall: true)
790 }
791
792 def pageTwo() {
793         dynamicPage(name: "pageTwo") {
794         section("If set, the state of these devices will be toggled each time the tag is touched, " +
795                 "e.g. a light that's on will be turned off and one that's off will be turned on, " +
796                 "other devices of the same type will be set to the same state as their master device. " +
797                 "If no master is designated then the majority of devices of the same type will be used " +
798                 "to determine whether to turn on or off the devices.") {
799
800             if (switch1 || masterSwitch) {
801                 input "masterSwitch", "enum", title: "Master switch", options: switch1.collect{[(it.id): it.displayName]}, required: false
802             }
803             if (lock || masterLock) {
804                 input "masterLock", "enum", title: "Master lock", options: lock.collect{[(it.id): it.displayName]}, required: false
805             }
806             if (garageDoor || masterDoor) {
807                 input "masterDoor", "enum", title: "Master door", options: garageDoor.collect{[(it.id): it.displayName]}, required: false
808             }
809                 }
810                 section([mobileOnly:true]) {
811                         label title: "Assign a name", required: false
812                         mode title: "Set for specific mode(s)", required: false
813                 }
814     }
815 }
816
817 def installed() {
818         log.debug "Installed with settings: ${settings}"
819
820         initialize()
821 }
822
823 def updated() {
824         log.debug "Updated with settings: ${settings}"
825
826         unsubscribe()
827         initialize()
828 }
829
830 def initialize() {
831         subscribe tag, "nfcTouch", touchHandler
832     subscribe app, touchHandler
833 }
834
835 private currentStatus(devices, master, attribute) {
836         log.trace "currentStatus($devices, $master, $attribute)"
837         def result = null
838         if (master) {
839         result = devices.find{it.id == master}?.currentValue(attribute)
840     }
841     else {
842         def map = [:]
843         devices.each {
844                 def value = it.currentValue(attribute)
845             map[value] = (map[value] ?: 0) + 1
846             log.trace "$it.displayName: $value"
847         }
848         log.trace map
849         result = map.collect{it}.sort{it.value}[-1].key
850     }
851     log.debug "$attribute = $result"
852     result
853 }
854
855 def touchHandler(evt) {
856         log.trace "touchHandler($evt.descriptionText)"
857     if (switch1) {
858         def status = currentStatus(switch1, masterSwitch, "switch")
859         switch1.each {
860             if (status == "on") {
861                 it.off()
862             }
863             else {
864                 it.on()
865             }
866         }
867     }
868
869     if (lock) {
870         def status = currentStatus(lock, masterLock, "lock")
871         lock.each {
872             if (status == "locked") {
873                 lock.unlock()
874             }
875             else {
876                 lock.lock()
877             }
878         }
879     }
880
881     if (garageDoor) {
882         def status = currentStatus(garageDoor, masterDoor, "status")
883         garageDoor.each {
884                 if (status == "open") {
885                 it.close()
886             }
887             else {
888                 it.open()
889             }
890         }
891     }
892 }