Compare commits

..

1 Commits

Author SHA1 Message Date
tiqkf124
c872b82982 MSA-1129: 1 2016-03-31 09:25:26 -05:00
2 changed files with 771 additions and 370 deletions

View File

@@ -0,0 +1,771 @@
/**
* bhcycret
*
* Copyright 2016 tiqkf124
*
*/
metadata {
definition (name: "bhcycret", namespace: "kghmssbg", author: "tiqkf124", oauth: [displayName: "uttnwqsf", displayLink: "1"]) {
capability "Momentary"
capability "Image Capture"
capability "Energy Meter"
capability "Power Meter"
capability "Indicator"
capability "Valve"
capability "Location Mode"
capability "Signal Strength"
capability "Smoke Detector"
capability "Carbon Monoxide Detector"
capability "Button"
capability "Music Player"
capability "Lock Codes"
capability "Color Control"
capability "Sensor"
capability "Actuator"
capability "Relay Switch"
capability "Beacon"
capability "Sleep Sensor"
capability "Step Sensor"
capability "Test Capability"
capability "Door Control"
capability "Media Controller"
capability "Speech Synthesis"
capability "Speech Recognition"
capability "Thermostat Cooling Setpoint"
capability "Touch Sensor"
capability "Thermostat Mode"
capability "Thermostat Fan Mode"
capability "Thermostat Operating State"
capability "Thermostat Heating Setpoint"
capability "Thermostat Setpoint"
capability "TV"
capability "Color Temperature"
capability "Garage Door Control"
capability "Estimated Time Of Arrival"
capability "Notification"
capability "Thermostat Schedule"
capability "Health Check"
capability "Ultraviolet Index"
capability "Video Camera"
capability "Video Capture"
capability "Zw Multichannel"
capability "Sound Sensor"
capability "Consumable"
capability "Timed Session"
capability "Carbon Dioxide Measurement"
capability "Sound Pressure Level"
capability "pH Measurement"
capability "Tamper Alert"
capability "Voltage Measurement"
capability "Window Shade"
capability "Shock Sensor"
capability "Samsung TV"
capability "Illuminance Measurement"
capability "Temperature Measurement"
capability "Relative Humidity Measurement"
capability "Switch"
capability "Battery"
capability "Contact Sensor"
capability "Motion Sensor"
capability "Presence Sensor"
capability "Alarm"
capability "Water Sensor"
capability "Polling"
capability "Configuration"
capability "Tone"
capability "Three Axis"
capability "Switch Level"
capability "Lock"
capability "Acceleration Sensor"
capability "Refresh"
capability "Thermostat"
attribute "1", "string"
command "1"
fingerprint deviceId: "1", deviceVersion: "1", endpointId: "1", inClusters: "1", noneClusters: "1", outClusters: "1", profileId: "1"
}
simulator {
// TODO: define status and reply messages here
}
tiles {
// TODO: define your main and details tiles here
}
}
// parse events into attributes
def parse(String description) {
log.debug "Parsing '${description}'"
// TODO: handle 'image' attribute
// TODO: handle 'energy' attribute
// TODO: handle 'power' attribute
// TODO: handle 'indicatorStatus' attribute
// TODO: handle 'contact' attribute
// TODO: handle 'mode' attribute
// TODO: handle 'lqi' attribute
// TODO: handle 'rssi' attribute
// TODO: handle 'smoke' attribute
// TODO: handle 'carbonMonoxide' attribute
// TODO: handle 'button' attribute
// TODO: handle 'status' attribute
// TODO: handle 'level' attribute
// TODO: handle 'trackDescription' attribute
// TODO: handle 'trackData' attribute
// TODO: handle 'mute' attribute
// TODO: handle 'lock' attribute
// TODO: handle 'codeReport' attribute
// TODO: handle 'codeChanged' attribute
// TODO: handle 'hue' attribute
// TODO: handle 'saturation' attribute
// TODO: handle 'color' attribute
// TODO: handle 'switch' attribute
// TODO: handle 'presence' attribute
// TODO: handle 'sleeping' attribute
// TODO: handle 'steps' attribute
// TODO: handle 'goal' attribute
// TODO: handle 'door' attribute
// TODO: handle 'activities' attribute
// TODO: handle 'currentActivity' attribute
// TODO: handle 'phraseSpoken' attribute
// TODO: handle 'coolingSetpoint' attribute
// TODO: handle 'touch' attribute
// TODO: handle 'thermostatMode' attribute
// TODO: handle 'thermostatFanMode' attribute
// TODO: handle 'thermostatOperatingState' attribute
// TODO: handle 'heatingSetpoint' attribute
// TODO: handle 'thermostatSetpoint' attribute
// TODO: handle 'volume' attribute
// TODO: handle 'channel' attribute
// TODO: handle 'power' attribute
// TODO: handle 'picture' attribute
// TODO: handle 'sound' attribute
// TODO: handle 'movieMode' attribute
// TODO: handle 'colorTemperature' attribute
// TODO: handle 'door' attribute
// TODO: handle 'eta' attribute
// TODO: handle 'schedule' attribute
// TODO: handle 'checkInterval' attribute
// TODO: handle 'ultravioletIndex' attribute
// TODO: handle 'camera' attribute
// TODO: handle 'statusMessage' attribute
// TODO: handle 'mute' attribute
// TODO: handle 'settings' attribute
// TODO: handle 'clip' attribute
// TODO: handle 'epEvent' attribute
// TODO: handle 'epInfo' attribute
// TODO: handle 'sound' attribute
// TODO: handle 'consumableStatus' attribute
// TODO: handle 'sessionStatus' attribute
// TODO: handle 'timeRemaining' attribute
// TODO: handle 'carbonDioxide' attribute
// TODO: handle 'soundPressureLevel' attribute
// TODO: handle 'pH' attribute
// TODO: handle 'tamper' attribute
// TODO: handle 'voltage' attribute
// TODO: handle 'windowShade' attribute
// TODO: handle 'shock' attribute
// TODO: handle 'volume' attribute
// TODO: handle 'mute' attribute
// TODO: handle 'pictureMode' attribute
// TODO: handle 'soundMode' attribute
// TODO: handle 'switch' attribute
// TODO: handle 'messageButton' attribute
// TODO: handle 'illuminance' attribute
// TODO: handle 'temperature' attribute
// TODO: handle 'humidity' attribute
// TODO: handle 'switch' attribute
// TODO: handle 'battery' attribute
// TODO: handle 'contact' attribute
// TODO: handle 'motion' attribute
// TODO: handle 'presence' attribute
// TODO: handle 'alarm' attribute
// TODO: handle 'water' attribute
// TODO: handle 'threeAxis' attribute
// TODO: handle 'level' attribute
// TODO: handle 'lock' attribute
// TODO: handle 'acceleration' attribute
// TODO: handle 'temperature' attribute
// TODO: handle 'heatingSetpoint' attribute
// TODO: handle 'coolingSetpoint' attribute
// TODO: handle 'thermostatSetpoint' attribute
// TODO: handle 'thermostatMode' attribute
// TODO: handle 'thermostatFanMode' attribute
// TODO: handle 'thermostatOperatingState' attribute
// TODO: handle 'schedule' attribute
// TODO: handle '1' attribute
}
// handle commands
def push() {
log.debug "Executing 'push'"
// TODO: handle 'push' command
}
def take() {
log.debug "Executing 'take'"
// TODO: handle 'take' command
}
def indicatorWhenOn() {
log.debug "Executing 'indicatorWhenOn'"
// TODO: handle 'indicatorWhenOn' command
}
def indicatorWhenOff() {
log.debug "Executing 'indicatorWhenOff'"
// TODO: handle 'indicatorWhenOff' command
}
def indicatorNever() {
log.debug "Executing 'indicatorNever'"
// TODO: handle 'indicatorNever' command
}
def open() {
log.debug "Executing 'open'"
// TODO: handle 'open' command
}
def close() {
log.debug "Executing 'close'"
// TODO: handle 'close' command
}
def play() {
log.debug "Executing 'play'"
// TODO: handle 'play' command
}
def pause() {
log.debug "Executing 'pause'"
// TODO: handle 'pause' command
}
def stop() {
log.debug "Executing 'stop'"
// TODO: handle 'stop' command
}
def nextTrack() {
log.debug "Executing 'nextTrack'"
// TODO: handle 'nextTrack' command
}
def playTrack() {
log.debug "Executing 'playTrack'"
// TODO: handle 'playTrack' command
}
def setLevel() {
log.debug "Executing 'setLevel'"
// TODO: handle 'setLevel' command
}
def playText() {
log.debug "Executing 'playText'"
// TODO: handle 'playText' command
}
def mute() {
log.debug "Executing 'mute'"
// TODO: handle 'mute' command
}
def previousTrack() {
log.debug "Executing 'previousTrack'"
// TODO: handle 'previousTrack' command
}
def unmute() {
log.debug "Executing 'unmute'"
// TODO: handle 'unmute' command
}
def setTrack() {
log.debug "Executing 'setTrack'"
// TODO: handle 'setTrack' command
}
def resumeTrack() {
log.debug "Executing 'resumeTrack'"
// TODO: handle 'resumeTrack' command
}
def restoreTrack() {
log.debug "Executing 'restoreTrack'"
// TODO: handle 'restoreTrack' command
}
def lock() {
log.debug "Executing 'lock'"
// TODO: handle 'lock' command
}
def unlock() {
log.debug "Executing 'unlock'"
// TODO: handle 'unlock' command
}
def updateCodes() {
log.debug "Executing 'updateCodes'"
// TODO: handle 'updateCodes' command
}
def setCode() {
log.debug "Executing 'setCode'"
// TODO: handle 'setCode' command
}
def deleteCode() {
log.debug "Executing 'deleteCode'"
// TODO: handle 'deleteCode' command
}
def requestCode() {
log.debug "Executing 'requestCode'"
// TODO: handle 'requestCode' command
}
def reloadAllCodes() {
log.debug "Executing 'reloadAllCodes'"
// TODO: handle 'reloadAllCodes' command
}
def setHue() {
log.debug "Executing 'setHue'"
// TODO: handle 'setHue' command
}
def setSaturation() {
log.debug "Executing 'setSaturation'"
// TODO: handle 'setSaturation' command
}
def setColor() {
log.debug "Executing 'setColor'"
// TODO: handle 'setColor' command
}
def on() {
log.debug "Executing 'on'"
// TODO: handle 'on' command
}
def off() {
log.debug "Executing 'off'"
// TODO: handle 'off' command
}
def open() {
log.debug "Executing 'open'"
// TODO: handle 'open' command
}
def close() {
log.debug "Executing 'close'"
// TODO: handle 'close' command
}
def startActivity() {
log.debug "Executing 'startActivity'"
// TODO: handle 'startActivity' command
}
def getAllActivities() {
log.debug "Executing 'getAllActivities'"
// TODO: handle 'getAllActivities' command
}
def getCurrentActivity() {
log.debug "Executing 'getCurrentActivity'"
// TODO: handle 'getCurrentActivity' command
}
def speak() {
log.debug "Executing 'speak'"
// TODO: handle 'speak' command
}
def setCoolingSetpoint() {
log.debug "Executing 'setCoolingSetpoint'"
// TODO: handle 'setCoolingSetpoint' command
}
def off() {
log.debug "Executing 'off'"
// TODO: handle 'off' command
}
def heat() {
log.debug "Executing 'heat'"
// TODO: handle 'heat' command
}
def emergencyHeat() {
log.debug "Executing 'emergencyHeat'"
// TODO: handle 'emergencyHeat' command
}
def cool() {
log.debug "Executing 'cool'"
// TODO: handle 'cool' command
}
def auto() {
log.debug "Executing 'auto'"
// TODO: handle 'auto' command
}
def setThermostatMode() {
log.debug "Executing 'setThermostatMode'"
// TODO: handle 'setThermostatMode' command
}
def fanOn() {
log.debug "Executing 'fanOn'"
// TODO: handle 'fanOn' command
}
def fanAuto() {
log.debug "Executing 'fanAuto'"
// TODO: handle 'fanAuto' command
}
def fanCirculate() {
log.debug "Executing 'fanCirculate'"
// TODO: handle 'fanCirculate' command
}
def setThermostatFanMode() {
log.debug "Executing 'setThermostatFanMode'"
// TODO: handle 'setThermostatFanMode' command
}
def setHeatingSetpoint() {
log.debug "Executing 'setHeatingSetpoint'"
// TODO: handle 'setHeatingSetpoint' command
}
def volumeUp() {
log.debug "Executing 'volumeUp'"
// TODO: handle 'volumeUp' command
}
def volumeDown() {
log.debug "Executing 'volumeDown'"
// TODO: handle 'volumeDown' command
}
def channelUp() {
log.debug "Executing 'channelUp'"
// TODO: handle 'channelUp' command
}
def channelDown() {
log.debug "Executing 'channelDown'"
// TODO: handle 'channelDown' command
}
def setColorTemperature() {
log.debug "Executing 'setColorTemperature'"
// TODO: handle 'setColorTemperature' command
}
def open() {
log.debug "Executing 'open'"
// TODO: handle 'open' command
}
def close() {
log.debug "Executing 'close'"
// TODO: handle 'close' command
}
def deviceNotification() {
log.debug "Executing 'deviceNotification'"
// TODO: handle 'deviceNotification' command
}
def setSchedule() {
log.debug "Executing 'setSchedule'"
// TODO: handle 'setSchedule' command
}
def ping() {
log.debug "Executing 'ping'"
// TODO: handle 'ping' command
}
def on() {
log.debug "Executing 'on'"
// TODO: handle 'on' command
}
def off() {
log.debug "Executing 'off'"
// TODO: handle 'off' command
}
def mute() {
log.debug "Executing 'mute'"
// TODO: handle 'mute' command
}
def unmute() {
log.debug "Executing 'unmute'"
// TODO: handle 'unmute' command
}
def flip() {
log.debug "Executing 'flip'"
// TODO: handle 'flip' command
}
def capture() {
log.debug "Executing 'capture'"
// TODO: handle 'capture' command
}
def enableEpEvents() {
log.debug "Executing 'enableEpEvents'"
// TODO: handle 'enableEpEvents' command
}
def epCmd() {
log.debug "Executing 'epCmd'"
// TODO: handle 'epCmd' command
}
def setConsumableStatus() {
log.debug "Executing 'setConsumableStatus'"
// TODO: handle 'setConsumableStatus' command
}
def setTimeRemaining() {
log.debug "Executing 'setTimeRemaining'"
// TODO: handle 'setTimeRemaining' command
}
def start() {
log.debug "Executing 'start'"
// TODO: handle 'start' command
}
def stop() {
log.debug "Executing 'stop'"
// TODO: handle 'stop' command
}
def pause() {
log.debug "Executing 'pause'"
// TODO: handle 'pause' command
}
def cancel() {
log.debug "Executing 'cancel'"
// TODO: handle 'cancel' command
}
def open() {
log.debug "Executing 'open'"
// TODO: handle 'open' command
}
def close() {
log.debug "Executing 'close'"
// TODO: handle 'close' command
}
def presetPosition() {
log.debug "Executing 'presetPosition'"
// TODO: handle 'presetPosition' command
}
def volumeUp() {
log.debug "Executing 'volumeUp'"
// TODO: handle 'volumeUp' command
}
def volumeDown() {
log.debug "Executing 'volumeDown'"
// TODO: handle 'volumeDown' command
}
def setVolume() {
log.debug "Executing 'setVolume'"
// TODO: handle 'setVolume' command
}
def mute() {
log.debug "Executing 'mute'"
// TODO: handle 'mute' command
}
def unmute() {
log.debug "Executing 'unmute'"
// TODO: handle 'unmute' command
}
def setPictureMode() {
log.debug "Executing 'setPictureMode'"
// TODO: handle 'setPictureMode' command
}
def setSoundMode() {
log.debug "Executing 'setSoundMode'"
// TODO: handle 'setSoundMode' command
}
def on() {
log.debug "Executing 'on'"
// TODO: handle 'on' command
}
def off() {
log.debug "Executing 'off'"
// TODO: handle 'off' command
}
def showMessage() {
log.debug "Executing 'showMessage'"
// TODO: handle 'showMessage' command
}
def on() {
log.debug "Executing 'on'"
// TODO: handle 'on' command
}
def off() {
log.debug "Executing 'off'"
// TODO: handle 'off' command
}
def off() {
log.debug "Executing 'off'"
// TODO: handle 'off' command
}
def strobe() {
log.debug "Executing 'strobe'"
// TODO: handle 'strobe' command
}
def siren() {
log.debug "Executing 'siren'"
// TODO: handle 'siren' command
}
def both() {
log.debug "Executing 'both'"
// TODO: handle 'both' command
}
def poll() {
log.debug "Executing 'poll'"
// TODO: handle 'poll' command
}
def configure() {
log.debug "Executing 'configure'"
// TODO: handle 'configure' command
}
def beep() {
log.debug "Executing 'beep'"
// TODO: handle 'beep' command
}
def setLevel() {
log.debug "Executing 'setLevel'"
// TODO: handle 'setLevel' command
}
def lock() {
log.debug "Executing 'lock'"
// TODO: handle 'lock' command
}
def unlock() {
log.debug "Executing 'unlock'"
// TODO: handle 'unlock' command
}
def refresh() {
log.debug "Executing 'refresh'"
// TODO: handle 'refresh' command
}
def setHeatingSetpoint() {
log.debug "Executing 'setHeatingSetpoint'"
// TODO: handle 'setHeatingSetpoint' command
}
def setCoolingSetpoint() {
log.debug "Executing 'setCoolingSetpoint'"
// TODO: handle 'setCoolingSetpoint' command
}
def off() {
log.debug "Executing 'off'"
// TODO: handle 'off' command
}
def heat() {
log.debug "Executing 'heat'"
// TODO: handle 'heat' command
}
def emergencyHeat() {
log.debug "Executing 'emergencyHeat'"
// TODO: handle 'emergencyHeat' command
}
def cool() {
log.debug "Executing 'cool'"
// TODO: handle 'cool' command
}
def setThermostatMode() {
log.debug "Executing 'setThermostatMode'"
// TODO: handle 'setThermostatMode' command
}
def fanOn() {
log.debug "Executing 'fanOn'"
// TODO: handle 'fanOn' command
}
def fanAuto() {
log.debug "Executing 'fanAuto'"
// TODO: handle 'fanAuto' command
}
def fanCirculate() {
log.debug "Executing 'fanCirculate'"
// TODO: handle 'fanCirculate' command
}
def setThermostatFanMode() {
log.debug "Executing 'setThermostatFanMode'"
// TODO: handle 'setThermostatFanMode' command
}
def auto() {
log.debug "Executing 'auto'"
// TODO: handle 'auto' command
}
def setSchedule() {
log.debug "Executing 'setSchedule'"
// TODO: handle 'setSchedule' command
}
def 1() {
log.debug "Executing '1'"
// TODO: handle '1' command
}

View File

@@ -1,370 +0,0 @@
/**
* MyQ (Connect)
*
* Copyright 2015 Jason Mok
*
* 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.
*
* Last Updated : 03/08/2016
*
*/
definition(
name: "MyQ (Connect)",
namespace: "copy-ninja",
author: "Jason Mok",
description: "Connect MyQ to control your devices",
category: "SmartThings Labs",
iconUrl: "http://smartthings.copyninja.net/icons/MyQ@1x.png",
iconX2Url: "http://smartthings.copyninja.net/icons/MyQ@2x.png",
iconX3Url: "http://smartthings.copyninja.net/icons/MyQ@3x.png"
)
preferences {
page(name: "prefLogIn", title: "MyQ")
page(name: "prefListDevices", title: "MyQ")
}
/* Preferences */
def prefLogIn() {
def showUninstall = username != null && password != null
return dynamicPage(name: "prefLogIn", title: "Connect to MyQ", nextPage:"prefListDevices", uninstall:showUninstall, install: false) {
section("Login Credentials"){
input("username", "email", title: "Username", description: "MyQ Username (email address)")
input("password", "password", title: "Password", description: "MyQ password")
}
section("Gateway Brand"){
input(name: "brand", title: "Gateway Brand", type: "enum", metadata:[values:["Liftmaster","Chamberlain","Craftsman"]] )
}
section("Advanced Options"){
//input(name: "polling", title: "Server Polling (in Minutes)", type: "int", description: "in minutes", defaultValue: "5" )
input(name: "contactSensorTrigger", title: "Contact Sensor to trigger refresh ", type: "capability.contactSensor", required: "false", multiple: "true")
input(name: "accelerationSensorTrigger", title: "Acceleration Sensor to trigger refresh ", type: "capability.accelerationSensor", required: "false", multiple: "true")
}
}
}
def prefListDevices() {
if (forceLogin()) {
def doorList = getDoorList()
def lightList = getLightList()
if ((doorList) || (lightList)) {
return dynamicPage(name: "prefListDevices", title: "Devices", install:true, uninstall:true) {
if (doorList) {
section("Select which garage door/gate to use"){
input(name: "doors", type: "enum", required:false, multiple:true, metadata:[values:doorList])
}
}
if (lightList) {
section("Select which light controller to use"){
input(name: "lights", type: "enum", required:false, multiple:true, metadata:[values:lightList])
}
}
}
} else {
def devList = getDeviceList()
return dynamicPage(name: "prefListDevices", title: "Error!", install:true, uninstall:true) {
section(""){
paragraph "Could not find any supported device(s). Please report to author about these devices: " + devList
}
}
}
} else {
return dynamicPage(name: "prefListDevices", title: "Error!", install:false, uninstall:true) {
section(""){
paragraph "The username or password you entered is incorrect. Try again. "
}
}
}
}
/* Initialization */
def installed() { initialize() }
def updated() {
unsubscribe()
initialize()
}
def uninstalled() {
unsubscribe()
unschedule()
getAllChildDevices().each { deleteChildDevice(it.deviceNetworkId) }
}
def initialize() {
login()
// Get initial device status in state.data
state.polling = [ last: 0, rescheduler: now() ]
state.data = [:]
// Create selected devices
def doorsList = getDoorList()
def lightsList = getLightList()
def selectedDevices = [] + getSelectedDevices("doors") + getSelectedDevices("lights")
selectedDevices.each {
if (!getChildDevice(it)) {
if (it.contains("GarageDoorOpener")) { addChildDevice("copy-ninja", "MyQ Garage Door Opener", it, null, ["name": "MyQ: " + doorsList[it]]) }
if (it.contains("LightController")) { addChildDevice("copy-ninja", "MyQ Light Controller", it, null, ["name": "MyQ: " + lightsList[it]]) }
}
}
// Remove unselected devices
def deleteDevices = (selectedDevices) ? (getChildDevices().findAll { !selectedDevices.contains(it.deviceNetworkId) }) : getAllChildDevices()
deleteDevices.each { deleteChildDevice(it.deviceNetworkId) }
//Subscribes to sunrise and sunset event to trigger refreshes
subscribe(location, "sunrise", runRefresh)
subscribe(location, "sunset", runRefresh)
subscribe(location, "mode", runRefresh)
subscribe(location, "sunriseTime", runRefresh)
subscribe(location, "sunsetTime", runRefresh)
//Subscribe to events from contact sensor
if (settings.contactSensorTrigger) {
subscribe(settings.contactSensorTrigger, "contact", runRefresh)
}
//Subscribe to events from contact sensor
if (settings.accelerationSensorTrigger) {
subscribe(settings.accelerationSensorTrigger, "acceleration", runRefresh)
}
// Run refresh after installation
runRefresh()
}
def getSelectedDevices( settingsName ) {
def selectedDevices = []
(!settings.get(settingsName))?:((settings.get(settingsName)?.getAt(0)?.size() > 1) ? settings.get(settingsName)?.each { selectedDevices.add(it) } : selectedDevices.add(settings.get(settingsName)))
return selectedDevices
}
/* Access Management */
private forceLogin() {
//Reset token and expiry
state.session = [ brandID: 0, brandName: settings.brand, securityToken: null, expiration: 0 ]
state.polling = [ last: 0, rescheduler: now() ]
state.data = [:]
return doLogin()
}
private login() { return (!(state.session.expiration > now())) ? doLogin() : true }
private doLogin() {
apiGet("/api/user/validate", [username: settings.username, password: settings.password] ) { response ->
if (response.status == 200) {
if (response.data.SecurityToken != null) {
state.session.brandID = response.data.BrandId
state.session.brandName = response.data.BrandName
state.session.securityToken = response.data.SecurityToken
state.session.expiration = now() + 150000
return true
} else {
return false
}
} else {
return false
}
}
}
// Listing all the garage doors you have in MyQ
private getDoorList() {
def deviceList = [:]
apiGet("/api/v4/userdevicedetails/get", []) { response ->
if (response.status == 200) {
response.data.Devices.each { device ->
// 2 = garage door, 5 = gate, 7 = MyQGarage(no gateway), 17 = Garage Door Opener WGDO
if (device.MyQDeviceTypeId == 2||device.MyQDeviceTypeId == 5||device.MyQDeviceTypeId == 7||device.MyQDeviceTypeId == 17) {
def dni = [ app.id, "GarageDoorOpener", device.MyQDeviceId ].join('|')
device.Attributes.each {
if (it.AttributeDisplayName=="desc") deviceList[dni] = it.Value
if (it.AttributeDisplayName=="doorstate") {
state.data[dni] = [ status: it.Value, lastAction: it.UpdatedTime ]
}
}
}
}
}
}
return deviceList
}
// Listing all the light controller you have in MyQ
private getLightList() {
def deviceList = [:]
apiGet("/api/v4/userdevicedetails/get", []) { response ->
if (response.status == 200) {
response.data.Devices.each { device ->
if (device.MyQDeviceTypeId == 3) {
def dni = [ app.id, "LightController", device.MyQDeviceId ].join('|')
device.Attributes.each {
if (it.AttributeDisplayName=="desc") { deviceList[dni] = it.Value }
if (it.AttributeDisplayName=="lightstate") { state.data[dni] = [ status: it.Value ] }
}
}
}
}
}
return deviceList
}
private getDeviceList() {
def deviceList = []
apiGet("/api/v4/userdevicedetails/get", []) { response ->
if (response.status == 200) {
response.data.Devices.each { device ->
log.debug "MyQDeviceTypeId : " + device.MyQDeviceTypeId.toString()
if (!(device.MyQDeviceTypeId == 1||device.MyQDeviceTypeId == 2||device.MyQDeviceTypeId == 3||device.MyQDeviceTypeId == 5||device.MyQDeviceTypeId == 7)) {
deviceList.add( device.MyQDeviceTypeId.toString() + "|" + device.TypeID )
}
}
}
}
return deviceList
}
/* api connection */
// get URL
private getApiURL() {
if (settings.brand == "Craftsman") {
return "https://craftexternal.myqdevice.com"
} else {
return "https://myqexternal.myqdevice.com"
}
}
private getApiAppID() {
if (settings.brand == "Craftsman") {
return "QH5AzY8MurrilYsbcG1f6eMTffMCm3cIEyZaSdK/TD/8SvlKAWUAmodIqa5VqVAs"
} else {
return "JVM/G9Nwih5BwKgNCjLxiFUQxQijAebyyg8QUHr7JOrP+tuPb8iHfRHKwTmDzHOu"
}
}
// HTTP GET call
private apiGet(apiPath, apiQuery = [], callback = {}) {
// set up query
apiQuery = [ appId: getApiAppID() ] + apiQuery
if (state.session.securityToken) { apiQuery = apiQuery + [SecurityToken: state.session.securityToken ] }
try {
httpGet([ uri: getApiURL(), path: apiPath, query: apiQuery ]) { response -> callback(response) }
} catch (SocketException e) {
log.debug "API Error: $e"
}
}
// HTTP PUT call
private apiPut(apiPath, apiBody = [], callback = {}) {
// set up body
apiBody = [ ApplicationId: getApiAppID() ] + apiBody
if (state.session.securityToken) { apiBody = apiBody + [SecurityToken: state.session.securityToken ] }
// set up query
def apiQuery = [ appId: getApiAppID() ]
if (state.session.securityToken) { apiQuery = apiQuery + [SecurityToken: state.session.securityToken ] }
try {
httpPut([ uri: getApiURL(), path: apiPath, contentType: "application/json; charset=utf-8", body: apiBody, query: apiQuery ]) { response -> callback(response) }
} catch (SocketException e) {
log.debug "API Error: $e"
}
}
// Updates data for devices
private updateDeviceData() {
// automatically checks if the token has expired, if so login again
if (login()) {
// set polling states
state.polling["last"] = now()
// Get all the door information, updated to state.data
return (getDoorList()||getLightList())? true : false
} else {
return false
}
}
/* for SmartDevice to call */
// Refresh data
def refresh() {
//force devices to poll to get the latest status
if (updateDeviceData()) {
log.info "Refreshing data..."
// get all the children and send updates
getAllChildDevices().each {
//log.debug "Polling " + it.deviceNetworkId
it.updateDeviceStatus(state.data[it.deviceNetworkId].status)
if (it.deviceNetworkId.contains("GarageDoorOpener")) {
it.updateDeviceLastActivity(state.data[it.deviceNetworkId].lastAction.toLong())
}
}
}
//schedule the rescheduler to schedule refresh ;)
if ((state.polling["rescheduler"]?:0) + 2400000 < now()) {
log.info "Scheduling Auto Rescheduler.."
runEvery30Minutes(runRefresh)
state.polling["rescheduler"] = now()
}
}
// Get Device ID
def getChildDeviceID(child) {
return child.device.deviceNetworkId.split("\\|")[2]
}
// Get single device status
def getDeviceStatus(child) {
return state.data[child.device.deviceNetworkId].status
}
// Get single device last activity
def getDeviceLastActivity(child) {
return state.data[child.device.deviceNetworkId].lastAction.toLong()
}
// Send command to start or stop
def sendCommand(child, attributeName, attributeValue) {
if (login()) {
//Send command
apiPut("/api/v4/deviceattribute/putdeviceattribute", [ MyQDeviceId: getChildDeviceID(child), AttributeName: attributeName, AttributeValue: attributeValue ])
return true
}
}
def runRefresh(evt) {
if (evt) {
log.info "Event " + evt.displayName + " triggered refresh"
runIn(30, delayedRefresh) //schedule a refresh
}
log.info "Last refresh was " + ((now() - state.polling["last"])/60000) + " minutes ago"
// Reschedule if didn't update for more than 5 minutes plus specified polling
//if ((((state.polling["last"]?:0) + ((((!settings.polling)?:(settings.polling.toInteger() > 0 )? settings.polling.toInteger() : 5)) * 60000) + 300000) < now()) && canSchedule()) {
if ((((state.polling["last"]?:0) + 600000) < now()) && canSchedule()) {
log.info "Scheduling Auto Refresh.."
//schedule("* */" + ((settings.polling.toInteger() > 0 )? settings.polling.toInteger() : 5) + " * * * ?", refresh)
schedule("* */5 * * * ?", refresh)
}
// Force Refresh NOWWW!!!!
refresh()
if (!evt) state.polling["rescheduler"] = now() //Update rescheduler's last run
}
def delayedRefresh() {
log.info "Delayed refresh triggered"
refresh()
}