/** * Garadget Connect * * Copyright 2016 Stuart Buchanan * * 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. * * 12/12/2017 V1.5 fixed bug introduced in v1.4 on initialize function. * 12/12/2017 V1.4 debug logging changes. - btrenbeath * 21/04/2017 V1.3 added url encoding to username and password for when special characters are used, with thanks to pastygangster * 20/03/2017 V1.2 updated to refresh the garadget devices every 1 minute which is the minimum schedule allowed in ST * 13/02/2016 V1.1 added the correct call for API url for EU/US servers, left to do: cleanup child devices when removed from setup * 12/02/2016 V1.0 initial release, left to do: cleanup child devices when removed from setup */ import java.net.URLEncoder import java.text.DecimalFormat import groovy.json.JsonSlurper import groovy.json.JsonOutput private apiUrl() { "https://api.particle.io" } private getVendorName() { "Garadget" } private getVendorTokenPath(){ "https://api.particle.io/oauth/token" } private getVendorIcon() { "https://dl.dropboxusercontent.com/s/lkrub180btbltm8/garadget_128.png" } private getClientId() { appSettings.clientId } private getClientSecret() { appSettings.clientSecret } private getServerUrl() { if(!appSettings.serverUrl){return getApiServerUrl()} } // Automatically generated. Make future change here. definition( name: "Garadget (Connect)", namespace: "fuzzysb", author: "Stuart Buchanan", description: "Garadget Integration", category: "SmartThings Labs", iconUrl: "https://dl.dropboxusercontent.com/s/lkrub180btbltm8/garadget_128.png", iconX2Url: "https://dl.dropboxusercontent.com/s/w8tvaedewwq56kr/garadget_256.png", iconX3Url: "https://dl.dropboxusercontent.com/s/5hiec37e0y5py06/garadget_512.png", oauth: true, singleInstance: true ) { appSetting "serverUrl" } preferences { page(name: "startPage", title: "Garadget Integration", content: "startPage", install: false) page(name: "Credentials", title: "Fetch OAuth2 Credentials", content: "authPage", install: false) page(name: "mainPage", title: "Garadget Integration", content: "mainPage") page(name: "completePage", title: "${getVendorName()} is now connected to SmartThings!", content: "completePage") page(name: "listDevices", title: "Garadget Devices", content: "listDevices", install: false) page(name: "badCredentials", title: "Invalid Credentials", content: "badAuthPage", install: false) } mappings { path("/receivedToken"){action: [POST: "receivedToken", GET: "receivedToken"]} } def startPage() { if (state.garadgetAccessToken) { return mainPage() } else { return authPage() } } def mainPage(){ def result = [success:false] if (!state.garadgetAccessToken) { createAccessToken() log.debug "About to create Smarthings Garadget access token." getToken(garadgetUsername, garadgetPassword) } if (state.garadgetAccessToken){ result.success = true } if(result.success == true) { return completePage() } else { return badAuthPage() } } def completePage(){ def description = "Tap 'Next' to proceed" return dynamicPage(name: "completePage", title: "Credentials Accepted!", nextPage: listDevices , uninstall: true, install:false) { section { href url: buildRedirectUrl("receivedToken"), style:"embedded", required:false, title:"${getVendorName()} is now connected to SmartThings!", description:description } } } def badAuthPage(){ log.debug "In badAuthPage" log.error "login result false" return dynamicPage(name: "badCredentials", title: "Garadget", install:false, uninstall:true, nextPage: Credentials) { section("") { paragraph "Please check your username and password" } } } def authPage() { log.debug "In authPage" if(canInstallLabs()) { def description = null log.debug "Prompting for Auth Details." description = "Tap to enter Credentials." return dynamicPage(name: "Credentials", title: "Authorize Connection", nextPage: mainPage, uninstall: false , install:false) { section("Generate Username and Password") { input "garadgetUsername", "text", title: "Your Garadget Username", required: true input "garadgetPassword", "password", title: "Your Garadget Password", required: true } } } else { def upgradeNeeded = """To use SmartThings Labs, your Hub should be completely up to date. To update your Hub, access Location Settings in the Main Menu (tap the gear next to your location name), select your Hub, and choose "Update Hub".""" return dynamicPage(name:"Credentials", title:"Upgrade needed!", nextPage:"", install:false, uninstall: true) { section { paragraph "$upgradeNeeded" } } } } def createChildDevice(deviceFile, dni, name, label) { log.debug "In createChildDevice" try{ def childDevice = addChildDevice("fuzzysb", deviceFile, dni, null, [name: name, label: label, completedSetup: true]) } catch (e) { log.error "Error creating device: ${e}" } } def listDevices() { log.debug "In listDevices" def options = getDeviceList() dynamicPage(name: "listDevices", title: "Choose devices", install: true) { section("Devices") { input "devices", "enum", title: "Select Device(s)", required: false, multiple: true, options: options, submitOnChange: true } } } def buildRedirectUrl(endPoint) { log.debug "In buildRedirectUrl" log.debug("returning: " + getServerUrl() + "/api/token/${state.accessToken}/smartapps/installations/${app.id}/${endPoint}") return getServerUrl() + "/api/token/${state.accessToken}/smartapps/installations/${app.id}/${endPoint}" } def receivedToken() { log.debug "In receivedToken" def html = """
Tap 'Done' to continue to Devices.