├── Link-Switch-And-Lock.groovy ├── README.md ├── Send-Events-to-EventGhost.groovy ├── Send-Trigger-to-Blue-Iris.groovy └── resources ├── BlueIris_logo.png ├── BlueIris_logo@2x.png ├── EventGhost_logo.png └── EventGhost_logo@2x.png /Link-Switch-And-Lock.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * Link Switch and Lock 3 | * 4 | * Link state between a switch and a lock. Switch On <=> Locked, Switch Off <=> Unlocked 5 | * 6 | * https://github.com/aderusha/SmartThings/blob/master/Link-Switch-And-Lock.groovy 7 | * Copyright 2015 aderusha 8 | * Version 1.0.0 - 2015-09-13 - Initial release 9 | * 10 | * I want to be able to control a lock device from a SmartApp that can only handle switch devices. 11 | * This SmartApp will link a lock and a button/switch device such that: 12 | * - Locking the lock will turn on the switch 13 | * - Unlocking the lock will turn off the switch 14 | * - Turning on the switch will lock the lock 15 | * - Turning off the switch will unlock the lock 16 | * 17 | * To use this SmartApp, first create a virtual device using the On/Off Button Tile device type. 18 | * Install this SmartApp, select your virtual On/Off Button Tile, then your lock. 19 | * 20 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 21 | * in compliance with the License. You may obtain a copy of the License at: 22 | * 23 | * http://www.apache.org/licenses/LICENSE-2.0 24 | * 25 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed 26 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License 27 | * for the specific language governing permissions and limitations under the License. 28 | * 29 | */ 30 | 31 | definition( 32 | name: "Link Switch and Lock", 33 | namespace: "aderusha", 34 | author: "aderusha", 35 | description: "Link state between a switch and a lock. Switch On <=> Locked, Switch Off <=> Unlocked", 36 | category: "Convenience", 37 | iconUrl: "https://s3.amazonaws.com/smartapp-icons/Solution/doors-locks.png", 38 | iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Solution/doors-locks@2x.png" 39 | ) 40 | 41 | preferences { 42 | section("When this switch is turned on") { 43 | input "switch1", "capability.switch", multiple: false, required: true 44 | } 45 | section("Lock this lock") { 46 | input "lock1", "capability.lock", multiple: false, required: true 47 | } 48 | } 49 | 50 | def installed() 51 | { 52 | subscribe(switch1, "switch.on", onHandler) 53 | subscribe(switch1, "switch.off", offHandler) 54 | subscribe(lock1, "lock.locked", lockedHandler) 55 | subscribe(lock1, "lock.unlocked", unlockedHandler) 56 | } 57 | 58 | def updated() 59 | { 60 | unsubscribe() 61 | subscribe(switch1, "switch.on", onHandler) 62 | subscribe(switch1, "switch.off", offHandler) 63 | subscribe(lock1, "lock.locked", lockedHandler) 64 | subscribe(lock1, "lock.unlocked", unlockedHandler) 65 | } 66 | 67 | def onHandler(evt) { 68 | log.debug evt.value 69 | log.debug "Locking lock: $lock1" 70 | lock1.lock() 71 | } 72 | 73 | def offHandler(evt) { 74 | log.debug evt.value 75 | log.debug "Unlocking lock: $lock1" 76 | lock1.unlock() 77 | } 78 | 79 | def lockedHandler(evt) { 80 | log.debug evt.value 81 | log.debug "Turning on switch: $switch1" 82 | switch1.on() 83 | } 84 | 85 | def unlockedHandler(evt) { 86 | log.debug evt.value 87 | log.debug "Turning off switch: $switch1" 88 | switch1.off() 89 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SmartThings 2 | Scripts and tools for SmartThings 3 | 4 | ### [Send-Events-to-EventGhost.groovy](https://github.com/aderusha/SmartThings/blob/master/Send-Events-to-EventGhost.groovy) 5 | This SmartApp will send selected events to an EventGhost server running the Webserver plugin. 6 | 7 | EventGhost is a Windows application used for event automation, find out more here: http://www.eventghost.org/ 8 | 9 | How to setup the EventGhost Webserver plugin: http://www.eventghost.org/mediawiki/index.php?title=Webserver 10 | 11 | ### [Link-Switch-And-Lock.groovy](https://github.com/aderusha/SmartThings/blob/master/Link-Switch-And-Lock.groovy) 12 | I want to be able to control a lock device from a SmartApp that can only handle switch devices. This SmartApp will link a lock and a button/switch device such that: 13 | * Locking the lock will turn on the switch 14 | * Unlocking the lock will turn off the switch 15 | * Turning on the switch will lock the lock 16 | * Turning off the switch will unlock the lock 17 | 18 | ### [Send-Trigger-to-Blue-Iris.groovy](https://github.com/aderusha/SmartThings/blob/master/Send-Trigger-to-Blue-Iris.groovy) 19 | This SmartApp will send selected events to a Blue Iris server on the local network. 20 | 21 | This requires the Blue Iris web server to allow un-authenticated connections. In settings > Web Server > Advanced > Authentication select "Non-LAN only" (preferred) or "No" to disable authentication altogether. 22 | -------------------------------------------------------------------------------- /Send-Events-to-EventGhost.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * Send Events to EventGhost 3 | * 4 | * Send SmartThings events to EventGhost 5 | * 6 | * https://github.com/aderusha/SmartThings/blob/master/Send-Events-to-EventGhost.groovy 7 | * Copyright 2015 aderusha 8 | * Version 1.0.0 - 2015-09-13 - Initial release 9 | * Version 1.1.0 - 2015-09-15 - Changed handling of binary(ish) vs non-binary values to allow sending 10 | * value data to EG to be handled via Python and eg.event.payload[] 11 | * Version 1.2.0 - 2016-04-18 - Added support for individual button values 12 | * 13 | * This SmartApp will send selected events to an EventGhost server running the Webserver plugin. 14 | * EventGhost is a Windows application used for event automation, find out more here: http://www.eventghost.org/ 15 | * How to setup the EventGhost Webserver plugin: http://www.eventghost.org/mediawiki/index.php?title=Webserver 16 | * 17 | * TODO: 18 | * - Currently doesn't support user authentication or SSL. EG Webserver authentication must be disabled by leaving 19 | * the username/password field in the plugin configuration blank 20 | * - Figure out how to monitor Sonos "musicPlayer" events 21 | * - Add additional capabilities to monitor 22 | * 23 | * ISSUES: 24 | * - "Color" values are not being received by EG, presumably due to the "#" character being mishandled somehow 25 | * 26 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 27 | * in compliance with the License. You may obtain a copy of the License at: 28 | * 29 | * http://www.apache.org/licenses/LICENSE-2.0 30 | * 31 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed 32 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License 33 | * for the specific language governing permissions and limitations under the License. 34 | * 35 | */ 36 | 37 | // button handling is kinda working but the handler is disabled. getting different responses from minimote vs scene 38 | // controller, should sort that out before tearing down the current minimote configs 39 | 40 | definition( 41 | name: "Send Events to EventGhost", 42 | namespace: "aderusha", 43 | author: "aderusha", 44 | description: "Send SmartThings events to EventGhost", 45 | category: "Convenience", 46 | iconUrl: "https://s3.amazonaws.com/aderusha/SmartThings/EventGhost_logo.png", 47 | iconX2Url: "https://s3.amazonaws.com/aderusha/SmartThings/EventGhost_logo@2x.png" 48 | ) 49 | 50 | preferences { 51 | section("EventGhost server address and port"){ 52 | input "egServer", "text", title: "Server", description: "EventGhost Web Server IP", required: true 53 | input "egPort", "number", title: "Port", description: "EventGhost Web Server Port", required: true, defaultValue: 80 54 | } 55 | section("EventGhost Command prefix"){ 56 | input "egPrefix", "text", title: "Command prefix", required: false, defaultValue: "ST" 57 | } 58 | section("Select events to be sent to EventGhost"){ 59 | input "mySwitch", "capability.switch", title: "Switches", required: false, multiple: true 60 | input "myDimmer", "capability.switchLevel", title: "Dimmers", required: false, multiple: true 61 | input "myColorControl", "capability.colorControl", title: "Color Controls", required: false, multiple: true 62 | input "myButton", "capability.button", title: "Buttons", required: false, multiple: true 63 | input "myMomentaryContact", "capability.momentary", title: "Momentary Contacts", required: false, multiple: true 64 | input "myMotion", "capability.motionSensor", title: "Motion Sensors", required: false, multiple: true 65 | input "myContact", "capability.contactSensor", title: "Contact Sensors", required: false, multiple: true 66 | input "myLock", "capability.lock", title: "Locks", required: false, multiple: true 67 | input "myThermostat", "capability.thermostat", title: "Thermostats", required: false, multiple: true 68 | input "myTemperature", "capability.temperatureMeasurement", title: "Temperature Sensors", required: false, multiple: true 69 | input "myBrightness", "capability.illuminanceMeasurement", title: "Light Sensors", required: false, multiple: true 70 | input "myHumidty", "capability.relativeHumidityMeasurement", title: "Humidty Sensors", required: false, multiple: true 71 | input "myEnergy", "capability.energyMeter", title: "Energy Sensors", required: false, multiple: true 72 | input "myPower", "capability.powerMeter", title: "Power Sensors", required: false, multiple: true 73 | input "myAcceleration", "capability.accelerationSensor", title: "Acceleration Sensors", required: false, multiple: true 74 | input "myPresence", "capability.presenceSensor", title: "Presence Sensors", required: false, multiple: true 75 | input "mySmoke", "capability.smokeDetector", title: "Smoke Sensors", required: false, multiple: true 76 | input "myWater", "capability.waterSensor", title: "Water Sensors", required: false, multiple: true 77 | input "myCO", "capability.carbonMonoxideDetector", title: "Carbon Monoxide Detectors", required: false, multiple: true 78 | } 79 | } 80 | 81 | def installed() { 82 | log.debug "Installed with settings: ${settings}" 83 | subscribeToEvents() 84 | } 85 | 86 | def updated() { 87 | log.debug "Updated with settings: ${settings}" 88 | unsubscribe() 89 | subscribeToEvents() 90 | } 91 | 92 | def subscribeToEvents() { 93 | subscribe(mySwitch, "switch", eventHandlerBinary) 94 | subscribe(myDimmer, "level", eventHandlerValue) 95 | subscribe(myColorControl, "color", eventHandlerValue) 96 | subscribe(myButton, "button", eventHandlerButton) 97 | subscribe(myMomentaryContact, "momentary", eventHandlerBinary) 98 | subscribe(myMotion, "motion", eventHandlerBinary) 99 | subscribe(myContact, "contact", eventHandlerBinary) 100 | subscribe(myLock, "lock", eventHandlerBinary) 101 | subscribe(myThermostat, "thermostat.thermostatMode", eventHandlerBinary) 102 | subscribe(myThermostat, "thermostat.thermostatFanMode", eventHandlerBinary) 103 | subscribe(myThermostat, "thermostat.thermostatOperatingState", eventHandlerBinary) 104 | subscribe(myThermostat, "thermostat.temperature", eventHandlerValue) 105 | subscribe(myThermostat, "thermostat.heatingSetpoint", eventHandlerValue) 106 | subscribe(myThermostat, "thermostat.coolingSetpoint", eventHandlerValue) 107 | subscribe(myThermostat, "thermostat.thermostatSetpoint", eventHandlerValue) 108 | subscribe(myTemperature, "temperature", eventHandlerValue) 109 | subscribe(myBrightness, "illuminance", eventHandlerValue) 110 | subscribe(myHumidty, "humidity", eventHandlerValue) 111 | subscribe(myEnergy, "energy", eventHandlerValue) 112 | subscribe(myPower, "power", eventHandlerValue) 113 | subscribe(myAcceleration, "acceleration", eventHandlerBinary) 114 | subscribe(myPresence, "presence", eventHandlerBinary) 115 | subscribe(mySmoke, "smoke", eventHandlerBinary) 116 | subscribe(myWater, "water", eventHandlerBinary) 117 | subscribe(myCO, "carbonMonoxide", eventHandlerBinary) 118 | } 119 | 120 | def eventHandlerBinary(evt) { 121 | def egHost = "${settings.egServer}:${settings.egPort}" 122 | def egRawCommand = "${settings.egPrefix}.${evt.displayName}.${evt.name}.${evt.value}" 123 | def egRestCommand = java.net.URLEncoder.encode(egRawCommand) 124 | log.debug "processed binary event ${evt.name} from device ${evt.displayName} with value ${evt.value} and data ${evt.data}" 125 | log.debug "egRestCommand: $egRestCommand" 126 | sendHubCommand(new physicalgraph.device.HubAction("""GET /?$egRestCommand HTTP/1.1\r\nHOST: $egHost\r\n\r\n""", physicalgraph.device.Protocol.LAN)) 127 | } 128 | 129 | def eventHandlerValue(evt) { 130 | def egHost = "${settings.egServer}:${settings.egPort}" 131 | def egRawCommand = "${settings.egPrefix}.${evt.displayName}.${evt.name}" 132 | def egRestCommand = java.net.URLEncoder.encode(egRawCommand) 133 | def egRestValue = java.net.URLEncoder.encode("${evt.value}") 134 | def egRestCommandValue = "$egRestCommand&$egRestValue" 135 | log.debug "processed data event ${evt.name} from device ${evt.displayName} with value ${evt.value} and data ${evt.data}" 136 | log.debug "egRestCommand: $egRestCommandValue" 137 | sendHubCommand(new physicalgraph.device.HubAction("""GET /?$egRestCommandValue HTTP/1.1\r\nHOST: $egHost\r\n\r\n""", physicalgraph.device.Protocol.LAN)) 138 | } 139 | 140 | def eventHandlerButton(evt) { 141 | def buttonNumber = evt.jsonData.buttonNumber 142 | def egHost = "${settings.egServer}:${settings.egPort}" 143 | def egRawCommand = "${settings.egPrefix}.${evt.displayName}.${evt.name}.$buttonNumber.${evt.value}" 144 | def egRestCommand = java.net.URLEncoder.encode(egRawCommand) 145 | log.debug "processed button event ${evt.name} from device ${evt.displayName} with value ${evt.value} and button $buttonNumber" 146 | log.debug "egRestCommand: $egRestCommand , [${egRestCommand}]" 147 | //sendHubCommand(new physicalgraph.device.HubAction("""GET /?$egRestCommand HTTP/1.1\r\nHOST: $egHost\r\n\r\n""", physicalgraph.device.Protocol.LAN)) 148 | 149 | sendHubCommand(new physicalgraph.device.HubAction( 150 | [ 151 | path: "/?$egRestCommand", 152 | method: "GET", 153 | HOST: "${egHost}", 154 | headers: [ 155 | "Host":"$egHost", 156 | "Accept":"application/json" 157 | ] 158 | ], 159 | null, 160 | null 161 | )) 162 | } 163 | -------------------------------------------------------------------------------- /Send-Trigger-to-Blue-Iris.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * Send Tigger to Blue Iris 3 | * 4 | * Trigger Blue Iris in response to SmartThings events 5 | * 6 | * https://github.com/aderusha/SmartThings/blob/master/Send-Trigger-to-Blue-Iris.groovy 7 | * Copyright 2015 aderusha 8 | * Version 0.0.1 - 2015-12-06 - Initial test release 9 | * 0.0.2 - 2015-12-06 - Only trigger on "motion" or "open", added more debug logging 10 | * 0.0.3 - 2015-12-10 - Actually tested this against Blue Iris and made it work. 11 | * 12 | * This SmartApp will send selected events to a Blue Iris server on the local network. 13 | * 14 | * This requires the Blue Iris web server to allow un-authenticated connections. In 15 | * settings > Web Server > Advanced > Authentication select "Non-LAN only" (preferred) 16 | * or "No" to disable authentication altogether. 17 | * 18 | * TODO: 19 | * - Add device types 20 | * - Add configurable conditions 21 | * 22 | * ISSUES: 23 | * - 24 | * 25 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 26 | * in compliance with the License. You may obtain a copy of the License at: 27 | * 28 | * http://www.apache.org/licenses/LICENSE-2.0 29 | * 30 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed 31 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License 32 | * for the specific language governing permissions and limitations under the License. 33 | * 34 | */ 35 | 36 | definition( 37 | name: "Send Tigger to Blue Iris", 38 | namespace: "aderusha", 39 | author: "aderusha", 40 | description: "Trigger Blue Iris in response to SmartThings events", 41 | category: "Convenience", 42 | iconUrl: "https://raw.githubusercontent.com/aderusha/SmartThings/master/resources/BlueIris_logo.png", 43 | iconX2Url: "https://raw.githubusercontent.com/aderusha/SmartThings/master/resources/BlueIris_logo%402x.png" 44 | ) 45 | 46 | preferences { 47 | section("Blue Iris server details"){ 48 | input "biServer", "text", title: "Server", description: "Blue Iris web server IP", required: true 49 | input "biPort", "number", title: "Port", description: "Blue Iris web server port", required: true 50 | input "biUser", "text", title: "User name", description: "Blue Iris user name", required: true 51 | input "biPass", "password", title: "Password", description: "Blue Iris password", required: true 52 | } 53 | section("Blue Iris Camera Name"){ 54 | input "biCamera", "text", title: "Camera Name", required: true 55 | } 56 | section("Select events to be sent to Blue Iris"){ 57 | input "myMotion", "capability.motionSensor", title: "Motion Sensors", required: false, multiple: true 58 | input "myContact", "capability.contactSensor", title: "Contact Sensors", required: false, multiple: true 59 | } 60 | } 61 | 62 | def installed() { 63 | log.debug "Installed with settings: ${settings}" 64 | subscribeToEvents() 65 | } 66 | 67 | def updated() { 68 | log.debug "Updated with settings: ${settings}" 69 | unsubscribe() 70 | subscribeToEvents() 71 | } 72 | 73 | def subscribeToEvents() { 74 | subscribe(myMotion, "motion", eventHandlerBinary) 75 | subscribe(myContact, "contact", eventHandlerBinary) 76 | } 77 | 78 | def eventHandlerBinary(evt) { 79 | if ((evt.value == "active") || (evt.value == "open")) { 80 | log.debug "processed event ${evt.name} from device ${evt.displayName} with value ${evt.value} and data ${evt.data}" 81 | def biHost = "${settings.biServer}:${settings.biPort}" 82 | def biRawCommand = "/admin?camera=${settings.biCamera}&trigger&user=${settings.biUser}&pw=${settings.biPass}" 83 | log.debug "sending GET to URL http://$biHost/$biRawCommand" 84 | def httpMethod = "GET" 85 | def httpRequest = [ 86 | method: httpMethod, 87 | path: biRawCommand, 88 | headers: [ 89 | HOST: biHost, 90 | Accept: "*/*", 91 | ] 92 | ] 93 | def hubAction = new physicalgraph.device.HubAction(httpRequest) 94 | sendHubCommand(hubAction) 95 | } 96 | } -------------------------------------------------------------------------------- /resources/BlueIris_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aderusha/SmartThings/3dc258d5f16ab6d935104c2764acd4377830b062/resources/BlueIris_logo.png -------------------------------------------------------------------------------- /resources/BlueIris_logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aderusha/SmartThings/3dc258d5f16ab6d935104c2764acd4377830b062/resources/BlueIris_logo@2x.png -------------------------------------------------------------------------------- /resources/EventGhost_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aderusha/SmartThings/3dc258d5f16ab6d935104c2764acd4377830b062/resources/EventGhost_logo.png -------------------------------------------------------------------------------- /resources/EventGhost_logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aderusha/SmartThings/3dc258d5f16ab6d935104c2764acd4377830b062/resources/EventGhost_logo@2x.png --------------------------------------------------------------------------------