diff --git a/smartapps/gideon-api/gideon.src/gideon.groovy b/smartapps/gideon-api/gideon.src/gideon.groovy index b277d25..2a537e5 100644 --- a/smartapps/gideon-api/gideon.src/gideon.groovy +++ b/smartapps/gideon-api/gideon.src/gideon.groovy @@ -1,253 +1,547 @@ -/** - * Gideon - * - * Copyright 2016 Nicola Russo - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License - * for the specific language governing permissions and limitations under the License. - * - */ -definition( - name: "Gideon", - namespace: "gideon.api", - author: "Braindrain Solutions", - description: "Gideon AI Smart app allows you to connect and control all of your SmartThings devices through the Gideon AI app, making your SmartThings devices even smarter.", - category: "Family", - iconUrl: "http://s33.postimg.org/t77u7y7v3/logo.png", - iconX2Url: "http://s33.postimg.org/t77u7y7v3/logo.png", - iconX3Url: "http://s33.postimg.org/t77u7y7v3/logo.png", - oauth: [displayName: "Gideon AI API", displayLink: "gideon.ai"]) - - -preferences { - section("Control these switches...") { - input "switches", "capability.switch", multiple:true - } - section("Control these motion sensors...") { - input "motions", "capability.motionSensor", multiple:true - } - section("Control these presence sensors...") { - input "presence_sensors", "capability.presenceSensor", multiple:true - } - section("Control these outlets...") { - input "outlets", "capability.switch", multiple:true - } - section("Control these locks...") { - input "locks", "capability.lock", multiple:true - } - section("Control these locks...") { - input "temperature_sensors", "capability.temperatureMeasurement" - } -} - -def installed() { - log.debug "Installed with settings: ${settings}" - - initialize() -} - -def updated() { - log.debug "Updated with settings: ${settings}" - - unsubscribe() - initialize() -} - -def initialize() { - // TODO: subscribe to attributes, devices, locations, etc. - subscribe(outlet, "energy", outletHandler) - subscribe(outlet, "switch", outletHandler) -} - -// TODO: implement event handlers -def outletHandler(evt) { - log.debug "$outlet.currentEnergy" - //TODO call G API -} - - -private device(it, type) { - it ? [id: it.id, label: it.label, type: type] : null -} - -//API Mapping -mappings { - path("/getalldevices") { - action: [ - GET: "getAllDevices" - ] - } - path("/doorlocks/:id/:command") { - action: [ - GET: "updateDoorLock" - ] - } - path("/doorlocks/:id") { - action: [ - GET: "getDoorLockStatus" - ] - } - path("/tempsensors/:id") { - action: [ - GET: "getTempSensorsStatus" - ] - } - path("/presences/:id") { - action: [ - GET: "getPresenceStatus" - ] - } - path("/motions/:id") { - action: [ - GET: "getMotionStatus" - ] - } - path("/outlets/:id") { - action: [ - GET: "getOutletStatus" - ] - } - path("/outlets/:id/:command") { - action: [ - GET: "updateOutlet" - ] - } - path("/switches/:command") { - action: [ - PUT: "updateSwitch" - ] - } -} - -//API Methods -def getAllDevices() { - def locks_list = locks.collect{device(it,"Lock")} - def presences_list = presence_sensors.collect{device(it,"Presence")} - def motions_list = motions.collect{device(it,"Motion")} - def outlets_list = outlets.collect{device(it,"Outlet")} - def switches_list = switches.collect{device(it,"Switch")} - def temp_list = temperature_sensors.collect{device(it,"Temperature")} - return [Locks: locks_list, Presences: presences_list, Motions: motions_list, Outlets: outlets_list, Switches: switches_list, Temperatures: temp_list] -} - -//LOCKS -def getDoorLockStatus() { - def device = locks.find { it.id == params.id } - if (!device) { - httpError(404, "Device not found") - } else { - return [Device_state: device.currentValue('lock')] - } -} - -def updateDoorLock() { - def command = params.command - def device = locks.find { it.id == params.id } - if (command){ - if (!device) { - httpError(404, "Device not found") - } else { - if(command == "toggle") - { - if(device.currentValue('lock') == "locked") - device.unlock(); - else - device.lock(); - - return [Device_id: params.id, result_action: "200"] - } - } - } -} - -//PRESENCE -def getPresenceStatus() { - - def device = presence_sensors.find { it.id == params.id } - if (!device) { - httpError(404, "Device not found") - } else { - return [Device_state: device.currentValue('presence')] - } -} - -//MOTION -def getMotionStatus() { - - def device = motions.find { it.id == params.id } - if (!device) { - httpError(404, "Device not found") - } else { - return [Device_state: device.currentValue('motion')] - } -} - -//OUTLET -def getOutletStatus() { - - def device = outlets.find { it.id == params.id } - if (!device) { - httpError(404, "Device not found") - } else { - return [Device_state: device.currentSwitch, Current_watt: device.currentValue("energy")] - } -} - -def updateOutlet() { - - def command = params.command - def device = outlets.find { it.id == params.id } - if (command){ - if (!device) { - httpError(404, "Device not found") - } else { - if(command == "toggle") - { - if(device.currentSwitch == "on") - device.off(); - else - device.on(); - - return [Device_id: params.id, result_action: "200"] - } - } - } -} - -//SWITCH -def updateSwitch() { - def command = params.command - def device = switches.find { it.id == params.id } - if (command){ - if (!device) { - httpError(404, "Device not found") - } else { - if(command == "toggle") - { - if(device.currentSwitch == "on") - device.off(); - else - device.on(); - - return [Device_id: params.id, result_action: "200"] - } - } - } -} - -//TEMPERATURE -def getTempSensorsStatus() { - - def device = temperature_sensors.find { it.id == params.id } - if (!device) { - httpError(404, "Device not found") - } else { - return [Device_state: device.currentValue('temperature')] - } -} \ No newline at end of file +/** + * Gideon + * + * Copyright 2016 Nicola Russo + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License + * for the specific language governing permissions and limitations under the License. + * + */ +definition( + name: "Gideon", + namespace: "gideon.api", + author: "Braindrain Solutions ltd", + 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.", + category: "Family", + iconUrl: "http://s33.postimg.org/t77u7y7v3/logo.png", + iconX2Url: "http://s33.postimg.org/t77u7y7v3/logo.png", + iconX3Url: "http://s33.postimg.org/t77u7y7v3/logo.png", + oauth: [displayName: "Gideon Smart Home API app", displayLink: "gideon.ai"]) + + +preferences { + section("Control these contact sensors...") { + input "contact", "capability.contactSensor", multiple:true, required:false + } + section("Control these switches...") { + input "switches", "capability.switch", multiple:true, required:false + } + section("Control these smoke alarms...") { + input "smoke_alarms", "capability.smokeDetector", multiple:true, required:false + } + section("Control these window shades...") { + input "shades", "capability.windowShade", multiple:true, required:false + } + section("Control these garage doors...") { + input "garage", "capability.garageDoorControl", multiple:true, required:false + } + section("Control these water sensors...") { + input "water_sensors", "capability.waterSensor", multiple:true, required:false + } + section("Control these motion sensors...") { + input "motions", "capability.motionSensor", multiple:true, required:false + } + section("Control these presence sensors...") { + input "presence_sensors", "capability.presenceSensor", multiple:true, required:false + } +/** section("Control these outlets...") { + input "outlets", "capability.switch", multiple:true, required:false + } +*/ + section("Control these power meters...") { + input "meters", "capability.powerMeter", multiple:true, required:false + } + section("Control these locks...") { + input "locks", "capability.lock", multiple:true, required:false + } + section("Control these temperature sensors...") { + input "temperature_sensors", "capability.temperatureMeasurement", multiple:true, required:false + } + section("Control these batteries...") { + input "batteries", "capability.battery", multiple:true, required:false + } +} + +def installed() { + log.debug "Installed with settings: ${settings}" + + initialize() +} + +def updated() { + log.debug "Updated with settings: ${settings}" + + unsubscribe() + initialize() +} + +def initialize() { +} + +private device(it, type) { + it ? [id: it.id, label: it.label, type: type] : null +} + +//API Mapping +mappings { + path("/getalldevices") { + action: [ + GET: "getAllDevices" + ] + } + path("/doorlocks/lock/:id") { + action: [ + GET: "lockDoorLock" + ] + } + path("/doorlocks/unlock/:id") { + action: [ + GET: "unlockDoorLock" + ] + } + path("/doorlocks/:id") { + action: [ + GET: "getDoorLockStatus" + ] + } + path("/contacts/:id") { + action: [ + GET: "getContactStatus" + ] + } + path("/smoke/:id") { + action: [ + GET: "getSmokeStatus" + ] + } + path("/shades/open/:id") { + action: [ + GET: "openShade" + ] + } + path("/shades/preset/:id") { + action: [ + GET: "presetShade" + ] + } + path("/shades/close/:id") { + action: [ + GET: "closeShade" + ] + } + path("/shades/:id") { + action: [ + GET: "getShadeStatus" + ] + } + path("/garage/open/:id") { + action: [ + GET: "openGarage" + ] + } + path("/garage/close/:id") { + action: [ + GET: "closeGarage" + ] + } + path("/garage/:id") { + action: [ + GET: "getGarageStatus" + ] + } + path("/watersensors/:id") { + action: [ + GET: "getWaterSensorStatus" + ] + } + path("/tempsensors/:id") { + action: [ + GET: "getTempSensorsStatus" + ] + } + path("/meters/:id") { + action: [ + GET: "getMeterStatus" + ] + } + path("/batteries/:id") { + action: [ + GET: "getBatteryStatus" + ] + } + path("/presences/:id") { + action: [ + GET: "getPresenceStatus" + ] + } + path("/motions/:id") { + action: [ + GET: "getMotionStatus" + ] + } +/** path("/outlets/:id") { + action: [ + GET: "getOutletStatus" + ] + } + path("/outlets/turnon/:id") { + action: [ + GET: "turnOnOutlet" + ] + } + path("/outlets/turnoff/:id") { + action: [ + GET: "turnOffOutlet" + ] + } +*/ + path("/switches/turnon/:id") { + action: [ + GET: "turnOnSwitch" + ] + } + path("/switches/turnoff/:id") { + action: [ + GET: "turnOffSwitch" + ] + } + path("/switches/:id") { + action: [ + GET: "getSwitchStatus" + ] + } +} + +//API Methods +def getAllDevices() { + def locks_list = locks.collect{device(it,"Lock")} + def contact_list = contact.collect{device(it,"Contact Sensor")} + def smokes_list = smoke_alarms.collect{device(it,"Smoke Alarm")} + def shades_list = shades.collect{device(it,"Window Shade")} + def garage_list = garage.collect{device(it,"Garage Door")} + def water_sensors_list = water_sensors.collect{device(it,"Water Sensor")} + def presences_list = presence_sensors.collect{device(it,"Presence")} + def motions_list = motions.collect{device(it,"Motion")} + /** def outlets_list = outlets.collect{device(it,"Outlet")} */ + def switches_list = switches.collect{device(it,"Switch")} + def temp_list = temperature_sensors.collect{device(it,"Temperature")} + def meters_list = meters.collect{device(it,"Power Meters")} + def battery_list = batteries.collect{device(it,"Batteries")} + return 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 +} + +//contact sensors +def getContactStatus() { + def device = contact.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + def args = getTempSensorsStatus(device.id) + return [Device_state: device.currentValue('contact')] + args + } +} + +//smoke detectors +def getSmokeStatus() { + def device = smoke_alarms.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + def bat = getBatteryStatus(device.id) + return [Device_state: device.currentValue('smoke')] + bat + } +} + +//garage +def getGarageStatus() { + def device = garage.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + return [Device_state: device.currentValue('door')] + } +} + +def openGarage() { + def device = garage.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + + device.open(); + + return [Device_id: params.id, result_action: "200"] + } + } + +def closeGarage() { + def device = garage.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + + device.close(); + + return [Device_id: params.id, result_action: "200"] + } + } +//shades +def getShadeStatus() { + def device = shades.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + return [Device_state: device.currentValue('windowShade')] + } +} + +def openShade() { + def device = shades.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + + device.open(); + + return [Device_id: params.id, result_action: "200"] + } + } + +def presetShade() { + def device = shades.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + + device.presetPosition(); + + return [Device_id: params.id, result_action: "200"] + } + } + +def closeShade() { + def device = shades.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + + device.close(); + + return [Device_id: params.id, result_action: "200"] + } + } + +//water sensor +def getWaterSensorStatus() { + def device = water_sensors.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + def bat = getBatteryStatus(device.id) + return [Device_state: device.currentValue('water')] + bat + } +} +//batteries +def getBatteryStatus() { + def device = batteries.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + return [Device_state: device.latestValue("battery")] + } +} + +def getBatteryStatus(id) { + def device = batteries.find { it.id == id } + if (!device) { + return [] + } else { + return [battery_state: device.latestValue("battery")] + } +} + +//LOCKS +def getDoorLockStatus() { + def device = locks.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + def bat = getBatteryStatus(device.id) + return [Device_state: device.currentValue('lock')] + bat + } +} + +def lockDoorLock() { + def device = locks.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + + device.lock(); + + return [Device_id: params.id, result_action: "200"] + } + } + +def unlockDoorLock() { + def device = locks.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + + device.unlock(); + + return [Device_id: params.id, result_action: "200"] + } + } +//PRESENCE +def getPresenceStatus() { + + def device = presence_sensors.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + def bat = getBatteryStatus(device.id) + return [Device_state: device.currentValue('presence')] + bat + } +} + +//MOTION +def getMotionStatus() { + + def device = motions.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + def args = getTempSensorsStatus(device.id) + return [Device_state: device.currentValue('motion')] + args + } +} + +//OUTLET +/** +def getOutletStatus() { + + def device = outlets.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + def watt = getMeterStatus(device.id) + return [Device_state: device.currentSwitch] + watt + } +} +*/ +def getMeterStatus() { + + def device = meters.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + return [Device_id: device.id, Device_type: device.type, Current_watt: device.currentValue("power")] + } +} + +def getMeterStatus(id) { + + def device = meters.find { it.id == id } + if (!device) { + return [] + } else { + return [Current_watt: device.currentValue("power")] + } +} + +/** +def turnOnOutlet() { + def device = outlets.find { it.id == params.id } + if (command){ + if (!device) { + httpError(404, "Device not found") + } else { + + device.on(); + + return [Device_id: params.id, result_action: "200"] + } + } +} +def turnOffOutlet() { + def device = outlets.find { it.id == params.id } + if (command){ + if (!device) { + httpError(404, "Device not found") + } else { + + device.off(); + + return [Device_id: params.id, result_action: "200"] + } + } +} +*/ +//SWITCH +def getSwitchStatus() { + def device = switches.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + return [Device_state: device.currentValue('switch')] + } +} + +def turnOnSwitch() { + def device = switches.find { it.id == params.id } + if (command){ + if (!device) { + httpError(404, "Device not found") + } else { + + device.on(); + + return [Device_id: params.id, result_action: "200"] + } + } +} + +def turnOffSwitch() { + def device = switches.find { it.id == params.id } + if (command){ + if (!device) { + httpError(404, "Device not found") + } else { + + device.on(); + + return [Device_id: params.id, result_action: "200"] + } + } +} + + +//TEMPERATURE +def getTempSensorsStatus() { + + def device = temperature_sensors.find { it.id == params.id } + if (!device) { + httpError(404, "Device not found") + } else { + def bat = getBatteryStatus(device.id) + return [Device_state: device.currentValue('temperature')] + bat + } +} + +def getTempSensorsStatus(id) { + def device = temperature_sensors.find { it.id == id } + if (!device) { + return [] + } else { + def bat = getBatteryStatus(device.id) + return [temperature: device.currentValue('temperature')] + bat + } + } \ No newline at end of file