Update WorkingFromHome.groovy
[smartapps.git] / official / gideon-smart-home.groovy
1 /**
2  *  Gideon
3  *
4  *  Copyright 2016 Nicola Russo
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
7  *  in compliance with the License. You may obtain a copy of the License at:
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
12  *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
13  *  for the specific language governing permissions and limitations under the License.
14  *
15  */
16 definition(
17     name: "Gideon Smart Home",
18     namespace: "gideon.api",
19     author: "Braindrain Solutions ltd",
20     description: "Gideon Smart Home SmartApp allows you to connect and control all of your SmartThings devices through the Gideon app, making your SmartThings devices even smarter.",
21     category: "Family",
22     iconUrl: "http://s33.postimg.org/t77u7y7v3/logo.png",
23     iconX2Url: "http://s33.postimg.org/t77u7y7v3/logo.png",
24     iconX3Url: "http://s33.postimg.org/t77u7y7v3/logo.png",
25     oauth: [displayName: "Gideon Smart Home API app", displayLink: "gideon.ai"])
26
27 preferences {
28         section("Control these contact sensors...") {
29         input "contact", "capability.contactSensor", multiple:true, required:false
30     }
31     section("Control these switch levels...") {
32         input "switchlevels", "capability.switchLevel", multiple:true, required:false
33     }
34 /*    section("Control these thermostats...") {
35         input "thermostats", "capability.thermostat", multiple:true, required:false
36     }*/
37     section("Control the color for these devices...") {
38         input "colors", "capability.colorControl", multiple:true, required:false
39     }
40     section("Control the color temperature for these devices...") {
41         input "kelvin", "capability.colorTemperature", multiple:true, required:false
42     }
43         section("Control these switches...") {
44         input "switches", "capability.switch", multiple:true, required:false
45     }
46     section("Control these smoke alarms...") {
47         input "smoke_alarms", "capability.smokeDetector", multiple:true, required:false
48     }
49     section("Control these window shades...") {
50         input "shades", "capability.windowShade", multiple:true, required:false
51     }
52     section("Control these garage doors...") {
53         input "garage", "capability.garageDoorControl", multiple:true, required:false
54     }
55     section("Control these water sensors...") {
56         input "water_sensors", "capability.waterSensor", multiple:true, required:false
57     }
58     section("Control these motion sensors...") {
59         input "motions", "capability.motionSensor", multiple:true, required:false
60     }
61     section("Control these presence sensors...") {
62         input "presence_sensors", "capability.presenceSensor", multiple:true, required:false
63     }
64         section("Control these outlets...") {
65         input "outlets", "capability.outlet", multiple:true, required:false
66     }
67     section("Control these power meters...") {
68         input "meters", "capability.powerMeter", multiple:true, required:false
69     }
70     section("Control these locks...") {
71         input "locks", "capability.lock", multiple:true, required:false
72     }
73     section("Control these temperature sensors...") {
74             input "temperature_sensors", "capability.temperatureMeasurement", multiple:true, required:false
75     }
76     section("Control these batteries...") {
77             input "batteries", "capability.battery", multiple:true, required:false
78     }
79 }
80
81 //API Mapping
82 mappings {
83    path("/getalldevices") {
84     action: [
85         GET: "getAllDevices"
86    ]
87   }
88   /*
89   path("/thermostat/setcool/:id/:temp") {
90     action: [
91       GET: "setCoolTemp"
92     ]
93   }
94   path("/thermostat/setheat/:id/:temp") {
95     action: [
96       GET: "setHeatTemp"
97     ]
98   }
99   path("/thermostat/setfanmode/:id/:mode") {
100     action: [
101       GET: "setFanMode"
102     ]
103   }
104   path("/thermostat/setmode/:id/:mode") {
105     action: [
106       GET: "setThermostatMode"
107     ]
108   }
109   path("/thermostat/:id") {
110     action: [
111       GET: "getThermostatStatus"
112     ]
113   }
114   */
115   path("/light/dim/:id/:dim") {
116     action: [
117       GET: "setLevelStatus"
118     ]
119   }
120   path("/light/kelvin/:id/:kelvin") {
121     action: [
122       GET: "setKelvin"
123     ]
124   }
125   path("/colorlight/:id/:hue/:sat") {
126     action: [
127       GET: "setColor"
128     ]
129   }
130   path("/light/status/:id") {
131     action: [
132       GET: "getLightStatus"
133     ]
134   }
135   path("/light/on/:id") {
136     action: [
137       GET: "turnOnLight"
138     ]
139   }
140   path("/light/off/:id") {
141     action: [
142       GET: "turnOffLight"
143     ]
144   }
145   path("/doorlocks/lock/:id") {
146     action: [
147       GET: "lockDoorLock"
148     ]
149   }
150   path("/doorlocks/unlock/:id") {
151     action: [
152       GET: "unlockDoorLock"
153     ]
154   }
155   path("/doorlocks/:id") {
156     action: [
157       GET: "getDoorLockStatus"
158     ]
159   }
160   path("/contacts/:id") {
161     action: [
162         GET: "getContactStatus"
163     ]
164   }
165   path("/smoke/:id") {
166     action: [
167         GET: "getSmokeStatus"
168         ]
169   }
170     path("/shades/open/:id") {
171     action: [
172       GET: "openShade"
173     ]
174   }
175   path("/shades/preset/:id") {
176     action: [
177       GET: "presetShade"
178     ]
179   }
180   path("/shades/close/:id") {
181     action: [
182       GET: "closeShade"
183     ]
184   }
185         path("/shades/:id") {
186     action: [
187         GET: "getShadeStatus"
188         ]
189 }
190     path("/garage/open/:id") {
191     action: [
192       GET: "openGarage"
193     ]
194   }
195   path("/garage/close/:id") {
196     action: [
197       GET: "closeGarage"
198     ]
199   }
200         path("/garage/:id") {
201     action: [
202                 GET: "getGarageStatus"
203         ]
204   }
205     path("/watersensors/:id") {
206     action: [
207                 GET: "getWaterSensorStatus"
208         ]
209   }
210         path("/tempsensors/:id") {
211     action: [
212       GET: "getTempSensorsStatus"
213     ]
214   }
215   path("/meters/:id") {
216     action: [
217       GET: "getMeterStatus"
218     ]
219   }
220   path("/batteries/:id") {
221     action: [
222       GET: "getBatteryStatus"
223     ]
224   }
225         path("/presences/:id") {
226     action: [
227       GET: "getPresenceStatus"
228     ]
229   }
230         path("/motions/:id") {
231     action: [
232       GET: "getMotionStatus"
233     ]
234   }
235         path("/outlets/:id") {
236     action: [
237       GET: "getOutletStatus"
238     ]
239   }
240         path("/outlets/turnon/:id") {
241     action: [
242       GET: "turnOnOutlet"
243     ]
244   }
245   path("/outlets/turnoff/:id") {
246     action: [
247       GET: "turnOffOutlet"
248     ]
249   }
250   path("/switches/turnon/:id") {
251     action: [
252       GET: "turnOnSwitch"
253     ]
254   }
255   path("/switches/turnoff/:id") {
256     action: [
257       GET: "turnOffSwitch"
258     ]
259   }
260   path("/switches/:id") {
261     action: [
262       GET: "getSwitchStatus"
263     ]
264   }
265 }
266
267 def installed() {
268         log.debug "Installed with settings: ${settings}"
269
270         initialize()
271 }
272
273 def updated() {
274         log.debug "Updated with settings: ${settings}"
275
276         unsubscribe()
277         initialize()
278 }
279
280 def initialize() {
281 }
282
283 private device(it, type) {
284         it ? [id: it.id, label: it.label, type: type] : null
285 }
286
287
288 //API Methods
289 def getAllDevices() {
290     def locks_list = locks.collect{device(it,"Lock")}
291     /*def thermo_list = thermostats.collect{device(it,"Thermostat")}*/
292     def colors_list = colors.collect{device(it,"Color")}
293     def kelvin_list = kelvin.collect{device(it,"Kelvin")}
294     def contact_list = contact.collect{device(it,"Contact Sensor")}
295     def smokes_list = smoke_alarms.collect{device(it,"Smoke Alarm")}
296     def shades_list = shades.collect{device(it,"Window Shade")}
297     def garage_list = garage.collect{device(it,"Garage Door")}
298     def water_sensors_list = water_sensors.collect{device(it,"Water Sensor")}
299     def presences_list = presence_sensors.collect{device(it,"Presence")}
300     def motions_list = motions.collect{device(it,"Motion")}
301         def outlets_list = outlets.collect{device(it,"Outlet")}
302     def switches_list = switches.collect{device(it,"Switch")}
303     def switchlevels_list = switchlevels.collect{device(it,"Switch Level")}
304     def temp_list = temperature_sensors.collect{device(it,"Temperature")}
305     def meters_list = meters.collect{device(it,"Power Meters")}
306     def battery_list = batteries.collect{device(it,"Batteries")}
307     return outlets_list + kelvin_list + colors_list + switchlevels_list + smokes_list + contact_list + water_sensors_list + shades_list + garage_list + locks_list + presences_list + motions_list + switches_list + temp_list + meters_list + battery_list
308 }
309
310 //light
311 def turnOnLight() {
312     def device = switches.find { it.id == params.id }
313         if (!device) {
314             httpError(404, "Device not found")
315         } else {
316             device.on();
317                   
318             return [Device_id: params.id, result_action: "200"]
319         }
320     }
321
322 def turnOffLight() {
323     def device = switches.find { it.id == params.id }
324         if (!device) {
325             httpError(404, "Device not found")
326         } else {
327             device.off();
328                   
329             return [Device_id: params.id, result_action: "200"]
330         }
331 }
332
333 def getLightStatus() {
334         def device = switches.find{ it.id == params.id }
335     if (!device) {
336             httpError(404, "Device not found")
337         } else {
338                 return [Status: device.currentValue('switch'), Dim: getLevelStatus(params.id), Color: getColorStatus(params.id), Kelvin: getKelvinStatus(params.id)]
339         }
340 }
341
342 //color control
343 def setColor() {
344     def device = colors.find { it.id == params.id }
345         if (!device) {
346             httpError(404, "Device not found")
347         } else {
348                 
349             def map = [hue:params.hue.toInteger(), saturation:params.sat.toInteger()]
350             
351             device.setColor(map);
352                   
353             return [Device_id: params.id, result_action: "200"]
354     }
355 }
356
357 def getColorStatus(id) {
358         def device = colors.find { it.id == id }
359     if (!device) {
360             return [Color: "none"]
361         } else {
362                 return [hue: device.currentValue('hue'), saturation: device.currentValue('saturation')]
363         }
364 }
365
366 //kelvin control
367 def setKelvin() {
368     def device = kelvin.find { it.id == params.id }
369         if (!device) {
370             httpError(404, "Device not found")
371         } else {
372         
373             device.setColorTemperature(params.kelvin.toInteger());
374                   
375             return [Device_id: params.id, result_action: "200"]
376     }
377 }
378
379 def getKelvinStatus(id) {
380         def device = kelvin.find { it.id == id }
381     if (!device) {
382             return [kelvin: "none"]
383         } else {
384                 return [kelvin: device.currentValue('colorTemperature')]
385         }
386 }
387
388 //switch level
389 def getLevelStatus(id) {
390         def device = switchlevels.find { it.id == id }
391     if (!device) {
392             [Level: "No dimmer"]
393         } else {
394                 return [Level: device.currentValue('level')]
395         }
396 }
397
398
399 def setLevelStatus() {
400         def device = switchlevels.find { it.id == params.id }
401     def level = params.dim
402     if (!device) {
403             httpError(404, "Device not found")
404         } else {
405                 device.setLevel(level.toInteger())
406                 return [result_action: "200", Level: device.currentValue('level')]
407         }
408 }
409
410
411 //contact sensors
412 def getContactStatus() {
413         def device = contact.find { it.id == params.id }
414     if (!device) {
415             httpError(404, "Device not found")
416         } else {
417                 def args = getTempSensorsStatus(device.id)
418                 return [Device_state: device.currentValue('contact')] + args
419         }
420 }
421
422 //smoke detectors
423 def getSmokeStatus() {
424         def device = smoke_alarms.find { it.id == params.id }
425     if (!device) {
426             httpError(404, "Device not found")
427         } else {
428         def bat = getBatteryStatus(device.id)
429                 return [Device_state: device.currentValue('smoke')] + bat
430         }
431 }
432
433 //garage
434 def getGarageStatus() {
435         def device = garage.find { it.id == params.id }
436     if (!device) {
437             httpError(404, "Device not found")
438         } else {
439                 return [Device_state: device.currentValue('door')]
440         }
441 }
442
443 def openGarage() {
444     def device = garage.find { it.id == params.id }
445     if (!device) {
446             httpError(404, "Device not found")
447         } else {
448             
449             device.open();
450                   
451             return [Device_id: params.id, result_action: "200"]                              
452             }
453     }
454
455 def closeGarage() {
456         def device = garage.find { it.id == params.id }
457     if (!device) {
458             httpError(404, "Device not found")
459         } else {
460             
461             device.close();
462                   
463             return [Device_id: params.id, result_action: "200"]                              
464             }
465     }
466 //shades
467 def getShadeStatus() {
468         def device = shades.find { it.id == params.id }
469     if (!device) {
470             httpError(404, "Device not found")
471         } else {
472                 return [Device_state: device.currentValue('windowShade')]
473         }
474 }
475
476 def openShade() {
477     def device = shades.find { it.id == params.id }
478     if (!device) {
479             httpError(404, "Device not found")
480         } else {
481             
482             device.open();
483                   
484             return [Device_id: params.id, result_action: "200"]                              
485             }
486     }
487     
488 def presetShade() {
489     def device = shades.find { it.id == params.id }
490     if (!device) {
491             httpError(404, "Device not found")
492         } else {
493             
494             device.presetPosition();
495                   
496             return [Device_id: params.id, result_action: "200"]                              
497             }
498     }
499
500 def closeShade() {
501         def device = shades.find { it.id == params.id }
502     if (!device) {
503             httpError(404, "Device not found")
504         } else {
505             
506             device.close();
507                   
508             return [Device_id: params.id, result_action: "200"]                              
509             }
510     }
511
512 //water sensor
513 def getWaterSensorStatus() {
514         def device = water_sensors.find { it.id == params.id }
515     if (!device) {
516             httpError(404, "Device not found")
517         } else {
518                 def bat = getBatteryStatus(device.id)
519                 return [Device_state: device.currentValue('water')] + bat
520         }
521 }
522 //batteries
523 def getBatteryStatus(id) {
524         def device = batteries.find { it.id == id }
525     if (!device) {
526             return []
527         } else {
528                 return [battery_state: device.latestValue("battery")]
529         }
530 }
531
532 //LOCKS
533 def getDoorLockStatus() {
534         def device = locks.find { it.id == params.id }
535     if (!device) {
536             httpError(404, "Device not found")
537         } else {
538                 def bat = getBatteryStatus(device.id)
539                 return [Device_state: device.currentValue('lock')] + bat
540         }
541 }
542
543 def lockDoorLock() {
544     def device = locks.find { it.id == params.id }
545     if (!device) {
546             httpError(404, "Device not found")
547         } else {
548             
549             device.lock();
550                   
551             return [Device_id: params.id, result_action: "200"]                              
552             }
553     }
554
555 def unlockDoorLock() {
556         def device = locks.find { it.id == params.id }
557     if (!device) {
558             httpError(404, "Device not found")
559         } else {
560             
561             device.unlock();
562                   
563             return [Device_id: params.id, result_action: "200"]                              
564             }
565     }
566 //PRESENCE
567 def getPresenceStatus() {
568
569         def device = presence_sensors.find { it.id == params.id }
570     if (!device) {
571             httpError(404, "Device not found")
572         } else {
573         def bat = getBatteryStatus(device.id)
574                 return [Device_state: device.currentValue('presence')] + bat
575    }
576 }
577
578 //MOTION
579 def getMotionStatus() {
580
581         def device = motions.find { it.id == params.id }
582     if (!device) {
583             httpError(404, "Device not found")
584         } else {
585                 def args = getTempSensorsStatus(device.id)
586                 return [Device_state: device.currentValue('motion')] + args
587    }
588 }
589
590 //OUTLET
591 def getOutletStatus() {
592
593     def device = outlets.find { it.id == params.id }
594     if (!device) {
595             device = switches.find { it.id == params.id }
596             if(!device) {
597                 httpError(404, "Device not found")
598                 }
599      }
600      def watt = getMeterStatus(device.id)
601         
602      return [Device_state: device.currentValue('switch')] + watt
603 }
604
605 def getMeterStatus(id) {
606
607     def device = meters.find { it.id == id }
608         if (!device) {
609             return []
610         } else {
611                 return [Current_watt: device.currentValue("power")]
612   }
613 }
614
615
616 def turnOnOutlet() {
617     def device = outlets.find { it.id == params.id }
618     if (!device) {
619             device = switches.find { it.id == params.id }
620             if(!device) {
621                 httpError(404, "Device not found")
622                 }
623      }
624      
625      device.on();
626                   
627      return [Device_id: params.id, result_action: "200"]
628 }
629
630 def turnOffOutlet() {
631     def device = outlets.find { it.id == params.id }
632     if (!device) {
633             device = switches.find { it.id == params.id }
634             if(!device) {
635                 httpError(404, "Device not found")
636                 }
637      }
638             
639      device.off();
640                   
641      return [Device_id: params.id, result_action: "200"]
642 }
643
644 //SWITCH
645 def getSwitchStatus() {
646         def device = switches.find { it.id == params.id }
647     if (!device) {
648             httpError(404, "Device not found")
649         } else {
650                 return [Device_state: device.currentValue('switch'), Dim: getLevelStatus(params.id)]
651         }
652 }
653
654 def turnOnSwitch() {
655     def device = switches.find { it.id == params.id }
656         if (!device) {
657             httpError(404, "Device not found")
658         } else {
659             
660             device.on();
661                   
662             return [Device_id: params.id, result_action: "200"]
663         }
664 }
665
666 def turnOffSwitch() {
667     def device = switches.find { it.id == params.id }
668         if (!device) {
669             httpError(404, "Device not found")
670         } else {
671             
672             device.off();
673                   
674             return [Device_id: params.id, result_action: "200"]
675         }
676 }
677
678
679 //TEMPERATURE
680 def getTempSensorsStatus(id) {  
681     def device = temperature_sensors.find { it.id == id }
682     if (!device) {
683             return []
684         } else {
685                 def bat = getBatteryStatus(device.id)
686                 return [temperature: device.currentValue('temperature')] + bat
687                 }
688    }