+++ /dev/null
-//
-alarmObject.setValue([name: "alarm", value: "both", deviceId: "alarmID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-alarmObject.setValue([name: "alarm", value: "siren", deviceId: "alarmID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-alarmObject.setValue([name: "alarm", value: "strobe", deviceId: "alarmID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-alarmObject.setValue([name: "alarm", value: "off", deviceId: "alarmID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-contactObject.setValue([name: "contact.closed", value: "closed", deviceId: "contactSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-contactObject.setValue([name: "contact.open", value: "open", deviceId: "contactSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-contactObject.setValue([name: "contact", value: "open", deviceId: "contactSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-contactObject.setValue([name: "contact", value: "close[d", deviceId: "contactSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-doorControlObject.setValue([name: "doorState", value: "closed", deviceId: "doorControlID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-doorControlObject.setValue([name: "doorState", value: "open", deviceId: "doorControlID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-locationObject.setValue([name: "Location", value: "away", deviceId: "locationID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-locationObject.setValue([name: "Location", value: "home", deviceId: "locationID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-locationObject.setValue([name: "Location", value: "night", deviceId: "locationID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-lockObject.setValue([name: "lock", value: "locked", deviceId: "lockID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-lockObject.setValue([name: "unlock", value: "unlocked ", deviceId: "lockID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-lockObject.setValue([name: "lock", value: "unlocked", deviceId: "lockID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-motionSensorObject.setValue([name: "motion", value: "active", deviceId: "motionSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-motionSensorObject.setValue([name: "motion", value: "inactive", deviceId: "motionSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-musicPlayerObject.setValue([name: "status", value: "playing", deviceId: "musicPlayerID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-musicPlayerObject.setValue([name: "status", value: "stopped", deviceId: "musicPlayerID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-musicPlayerObject.setValue([name: "status", value: "paused", deviceId: "musicPlayerID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-musicPlayerObject.setValue([name: "level", value: "36"/*A number between 0 to 100 as a charge*/, deviceId: "musicPlayerID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-musicPlayerObject.setValue([name: "trackDescription", value: "someDescriptions", deviceId: "musicPlayerID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-musicPlayerObject.setValue([name: "trackData", value: "someTrack", deviceId: "musicPlayerID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-musicPlayerObject.setValue([name: "mute", value: "umuted", deviceId: "musicPlayerID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-musicPlayerObject.setValue([name: "mute", value: "muted", deviceId: "musicPlayerID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-presenceSensorObject.setValue([name: "presence", value: "present", deviceId: "presenceSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"presence":"1","dni":"mobile0"}'])
-presenceSensorObject.setValue([name: "presence", value: "not present", deviceId: "presenceSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"presence":"1","dni":"mobile0"}'])
-presenceSensorObject.setValue([name: "presence", value: "presence.present", deviceId: "presenceSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"presence":"1","dni":"mobile0"}'])
-
-smokeDetectorObject.setValue([name: "smoke", value: "clear", deviceId: "smokeDetectorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-smokeDetectorObject.setValue([name: "smoke", value: "detected", deviceId: "smokeDetectorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-smokeDetectorObject.setValue([name: "smoke", value: "tested", deviceId: "smokeDetectorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-smokeDetectorObject.setValue([name: "carbonMonoxide", value: "clear", deviceId: "smokeDetectorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-smokeDetectorObject.setValue([name: "carbonMonoxide", value: "detected", deviceId: "smokeDetectorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-smokeDetectorObject.setValue([name: "carbonMonoxide", value: "tested", deviceId: "smokeDetectorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-smokeDetectorObject.setValue([name: "battery", value: "5"/*A number between 0 to 100 as a charge*/, deviceId: "smokeDetectorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-thermostatObject.setValue([name: "thermostatMode", value: "auto", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-thermostatObject.setValue([name: "thermostatMode", value: "cool", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-thermostatObject.setValue([name: "thermostatMode", value: "emergencyHeat", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-thermostatObject.setValue([name: "thermostatMode", value: "heat", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-thermostatObject.setValue([name: "thermostatMode", value: "off", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-thermostatObject.setValue([name: "temperature", value: "55", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-thermostatObject.setValue([name: "heatingSetpoint", value: "40", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-thermostatObject.setValue([name: "coolingSetpoint", value: "60", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-thermostatObject.setValue([name: "thermostatSetpoint", value: "50", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-thermostatObject.setValue([name: "thermostatFanMode", value: "auto", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-thermostatObject.setValue([name: "thermostatFanMode", value: "fanCirculate", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-thermostatObject.setValue([name: "thermostatFanMode", value: "circulate", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-thermostatObject.setValue([name: "thermostatFanMode", value: "fanOn", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-thermostatObject.setValue([name: "thermostatFanMode", value: "on", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-thermostatObject.setValue([name: "thermostatOperatingState", value: "auto", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-thermostatObject.setValue([name: "thermostatOperatingState", value: "cool", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-thermostatObject.setValue([name: "thermostatOperatingState", value: "off", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-thermostatObject.setValue([name: "thermostatOperatingState", value: "emergencyHeat", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-thermostatObject.setValue([name: "thermostatOperatingState", value: "heat", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-switchObject.setValue([name: "switch", value: "off", deviceId: "switchID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-switchObject.setValue([name: "switch", value: "on", deviceId: "switchID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-appObject.setValue([name: "Touched", value: "touched", deviceId: "touchedSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-touchSensorObject.setValue([name: "nfcTouch", value: "touched", deviceId: "nfcSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-aeonKeyFobObject.setValue([name: "button", value: "pushed", deviceId: "aeonKeyFobID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-aeonKeyFobObject.setValue([name: "button", value: "held", deviceId: "aeonKeyFobID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-accelerationSensorObject.setValue([name: "acceleration", value: "active", deviceId: "accelerationSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-accelerationSensorObject.setValue([name: "acceleration", value: "inactive", deviceId: "accelerationSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-batteryObject.setValue([name: "battery", value: "50"/*number between 0 to 100 as a string*/, deviceId: "batteryID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-beaconSensorObject.setValue([name: "presence", value: "present", deviceId: "beaconeSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"presence":"1","dni":"mobile0"}'])
-beaconSensorObject.setValue([name: "presence", value: "not present", deviceId: "beaconSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"presence":"1","dni":"mobile0"}'])
-
-carbonMonoxideDetectorObject.setValue([name: "carbonMonoxide", value: "clear", deviceId: "carbonMonoxideDetectorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-carbonMonoxideDetectorObject.setValue([name: "carbonMonoxide", value: "detected", deviceId: "carbonMonoxideDetectorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-carbonMonoxideDetectorObject.setValue([name: "carbonMonoxide", value: "tested", deviceId: "carbonMonoxideDetectorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-colorControlObject.setValue([name: "color", value: "red", deviceId: "colorControlID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-colorControlObject.setValue([name: "hue", value: "50", deviceId: "colorControlID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-colorControlObject.setValue([name: "saturation", value: "50", deviceId: "colorControlID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-energyMeterObject.setValue([name: "energy", value: "45"/*A number between 0 to 100 as a charge*/, deviceId: "energyMeterID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-illuminanceMeasurementObject.setValue([name: "illuminance", value: "70"/*A number between 0 to 100 as a charge*/, deviceId: "illuminanceMeasurementID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-powerMeterObject.setValue([name: "power", value: "70"/*A number between 0 to 100 as a charge*/, deviceId: "powerMeterID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-humidityMeasurementObject.setValue([name: "humidity", value: "70"/*A number between 0 to 100 as a charge*/, deviceId: "humidityMeasurementID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-switchObject.setValue([name: "switch", value: "off", deviceId: "relaySwitchID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-switchObject.setValue([name: "switch", value: "on", deviceId: "relaySwitchID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-sleepSensorObject.setValue([name: "sleeping", value: "sleeping", deviceId: "sleepSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-sleepSensorObject.setValue([name: "sleeping", value: "not sleeping", deviceId: "sleepSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-stepSensorObject.setValue([name: "goal", value: "100"/*A number*/, deviceId: "stepSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-stepSensorObject.setValue([name: "steps", value: "46"/*A number*/, deviceId: "stepSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-switchLevelObject.setValue([name: "level", value: "45"/*A number between 0 to 100*/, deviceId: "switchLevelID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-temperatureMeasurementObject.setValue([name: "temperature", value: "45"/*A number between 0 to 100*/, deviceId: "temperatureMeasurementID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-valveObject.setValue([name: "contact", value: "closed", deviceId: "valveID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-valveObject.setValue([name: "contact", value: "open", deviceId: "valveID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-
-waterSensorObject.setValue([name: "water", value: "dry", deviceId: "waterSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-waterSensorObject.setValue([name: "water", value: "wet", deviceId: "waterSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
-/**
- * groveStreams
- *
- * Copyright 2014 Yves Racine
- *
- * LinkedIn profile: ca.linkedin.com/pub/yves-racine-m-sc-a/0/406/4b/
- *
- * Developer retains all right, title, copyright, and interest, including all copyright, patent rights, trade secret
- * in the Background technology. May be subject to consulting fees under the Agreement between the Developer and the Customer.
- * Developer grants a non exclusive perpetual license to use the Background technology in the Software developed for and delivered
- * to Customer under this Agreement. However, the Customer shall make no commercial use of the Background technology without
- * Developer's written consent.
- *
- * 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.
- * Software Distribution is restricted and shall be done only with Developer's written approval.
- *
- * Based on code from Jason Steele & Minollo
- * Adapted to be compatible with MyEcobee and My Automatic devices which are available at my store:
- * http://www.ecomatiqhomes.com/#!store/tc3yr
- *
- */
definition(
- name: "groveStreams",
- namespace: "yracine",
- author: "Yves Racine",
- description: "Log to groveStreams and send data streams based on devices selection",
- category: "My Apps",
- iconUrl: "https://s3.amazonaws.com/smartapp-icons/Partner/ecobee.png",
- iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/ecobee@2x.png"
+ name: "Enhanced Auto Lock Door",
+ namespace: "Lock Auto Super Enhanced",
+ author: "Arnaud",
+ description: "Automatically locks a specific door after X minutes when closed and unlocks it when open after X seconds.",
+ category: "Safety & Security",
+ iconUrl: "http://www.gharexpert.com/mid/4142010105208.jpg",
+ iconX2Url: "http://www.gharexpert.com/mid/4142010105208.jpg"
)
-
-
-preferences {
- section("About") {
- paragraph "groveStreams, the smartapp that sends your device states to groveStreams for data correlation"
- paragraph "Version 2.2.2"
- paragraph "If you like this smartapp, please support the developer via PayPal and click on the Paypal link below "
- href url: "https://www.paypal.me/ecomatiqhomes",
- title:"Paypal donation..."
- paragraph "Copyright©2014 Yves Racine"
- href url:"http://github.com/yracine/device-type.myecobee", style:"embedded", required:false, title:"More information..."
- description: "http://github.com/yracine"
- }
- section("Log devices...") {
- input "temperatures", "capability.temperatureMeasurement", title: "Temperatures", required: false, multiple: true
- input "thermostats", "capability.thermostat", title: "Thermostats", required: false, multiple: true
- //input "ecobees", "device.myEcobeeDevice", title: "Ecobees", required: false, multiple: true
- input "automatic", "capability.presenceSensor", title: "Automatic Connected Device(s)", required: false, multiple: true
- input "detectors", "capability.smokeDetector", title: "Smoke/CarbonMonoxide Detectors", required: false, multiple: true
- input "humidities", "capability.relativeHumidityMeasurement", title: "Humidity sensors", required: false, multiple: true
- input "waters", "capability.waterSensor", title: "Water sensors", required: false, multiple: true
- input "illuminances", "capability.illuminanceMeasurement", title: "Illuminance sensor", required: false, multiple: true
- input "locks", "capability.lock", title: "Locks", required: false, multiple: true
- input "contacts", "capability.contactSensor", title: "Doors open/close", required: false, multiple: true
- input "accelerations", "capability.accelerationSensor", title: "Accelerations", required: false, multiple: true
- input "motions", "capability.motionSensor", title: "Motions", required: false, multiple: true
- input "presence", "capability.presenceSensor", title: "Presence", required: false, multiple: true
- input "switches", "capability.switch", title: "Switches", required: false, multiple: true
- input "dimmerSwitches", "capability.switchLevel", title: "Dimmer Switches", required: false, multiple: true
- input "batteries", "capability.battery", title: "Battery-powered devices", required: false, multiple: true
- input "powers", "capability.powerMeter", title: "Power Meters", required: false, multiple: true
- input "energys", "capability.energyMeter", title: "Energy Meters", required: false, multiple: true
-
- }
-
- section("GroveStreams Feed PUT API key...") {
- input "channelKey", "text", title: "API key"
- }
- section("Sending data at which interval in minutes (default=5)?") {
- input "givenInterval", "number", title: 'Send Data Interval', required: false
- }
-}
-
-def installed() {
- initialize()
-}
-
-def updated() {
- unsubscribe()
- unschedule()
- initialize()
-}
-
-def initialize() {
- subscribe(temperatures, "temperature", handleTemperatureEvent)
- subscribe(humidities, "humidity", handleHumidityEvent)
- subscribe(waters, "water", handleWaterEvent)
- subscribe(waters, "water", handleWaterEvent)
- subscribe(detectors, "smoke", handleSmokeEvent)
- subscribe(detectors, "carbonMonoxide", handleCarbonMonoxideEvent)
- subscribe(illuminances, "illuminance", handleIlluminanceEvent)
- subscribe(contacts, "contact", handleContactEvent)
- subscribe(locks, "lock", handleLockEvent)
- subscribe(accelerations, "acceleration", handleAccelerationEvent)
- subscribe(motions, "motion", handleMotionEvent)
- subscribe(presence, "presence", handlePresenceEvent)
- subscribe(switches, "switch", handleSwitchEvent)
- subscribe(dimmerSwitches, "switch", handleSwitchEvent)
- subscribe(dimmerSwitches, "level", handleSetLevelEvent)
- subscribe(batteries, "battery", handleBatteryEvent)
- subscribe(powers, "power", handlePowerEvent)
- subscribe(energys, "energy", handleEnergyEvent)
- subscribe(energys, "cost", handleCostEvent)
- subscribe(thermostats, "heatingSetpoint", handleHeatingSetpointEvent)
- subscribe(thermostats, "coolingSetpoint", handleCoolingSetpointEvent)
- subscribe(thermostats, "thermostatMode", handleThermostatModeEvent)
- subscribe(thermostats, "fanMode", handleFanModeEvent)
- subscribe(thermostats, "thermostatOperatingState", handleThermostatOperatingStateEvent)
- /*subscribe(ecobees, "dehumidifierMode", handleDehumidifierModeEvent)
- subscribe(ecobees, "equipmentStatus", handleEquipmentStatusEvent)
- subscribe(ecobees, "dehumidifierLevel", handleDehumidifierLevelEvent)
- subscribe(ecobees, "humidifierMode", handleHumidifierModeEvent)
- subscribe(ecobees, "humidifierLevel", handleHumidifierLevelEvent)
- subscribe(ecobees, "fanMinOnTime", handleFanMinOnTimeEvent)
- subscribe(ecobees, "ventilatorMode", handleVentilatorModeEvent)
- subscribe(ecobees, "ventilatorMinOnTime", handleVentilatorMinOnTimeEvent)
- subscribe(ecobees, "programScheduleName", handleProgramNameEvent)
- subscribe(ecobees, "auxHeat1RuntimeDaily", handleDailyStats)
- subscribe(ecobees, "auxHeat2RuntimeDaily", handleDailyStats)
- subscribe(ecobees, "auxHeat3RuntimeDaily", handleDailyStats)
- subscribe(ecobees, "compCool1RuntimeDaily", handleDailyStats)
- subscribe(ecobees, "compCool2RuntimeDaily", handleDailyStats)
- subscribe(ecobees, "fanRuntimeDaily", handleDailyStats)
- subscribe(ecobees, "humidifierRuntimeDaily", handleDailyStats)
- subscribe(ecobees, "dehumidifierRuntimeDaily", handleDailyStats)
- subscribe(ecobees, "ventilatorRuntimeDaily", handleDailyStats)
- subscribe(ecobees, "presence", handlePresenceEvent)
- subscribe(ecobees, "compCool2RuntimeDaily", handleDailyStats)*/
- subscribe(automatic, "yesterdayTripsAvgAverageKmpl",handleDailyStats)
- subscribe(automatic, "yesterdayTripsAvgDistanceM",handleDailyStats)
- subscribe(automatic, "yesterdayTripsAvgDurationS",handleDailyStats)
- subscribe(automatic, "yesterdayTotalDistanceM",handleDailyStats)
- subscribe(automatic, "yesterdayTripsAvgFuelVolumeL",handleDailyStats)
- subscribe(automatic, "yesterdayTotalFuelVolumeL",handleDailyStats)
- subscribe(automatic, "yesterdayTotalDurationS:",handleDailyStats)
- subscribe(automatic, "yesterdayTotalNbTrips",handleDailyStats)
- subscribe(automatic, "yesterdayTotalHardAccels",handleDailyStats)
- subscribe(automatic, "yesterdayTotalHardBrakes:",handleDailyStats)
- subscribe(automatic, "yesterdayTripsAvgScoreSpeeding",handleDailyStats)
- subscribe(automatic, "yesterdayTripsAvgScoreEvents",handleDailyStats)
- def queue = []
- atomicState.queue=queue
-
- if (atomicState.queue==null) {
- atomicState.queue = []
- }
- atomicState?.poll = [ last: 0, rescheduled: now() ]
-
- Integer delay = givenInterval ?: 5 // By default, schedule processQueue every 5 min.
- log.debug "initialize>scheduling processQueue every ${delay} minutes"
-
- //Subscribe to different events (ex. sunrise and sunset events) to trigger rescheduling if needed
- subscribe(location, "sunrise", rescheduleIfNeeded)
- subscribe(location, "sunset", rescheduleIfNeeded)
- subscribe(location, "mode", rescheduleIfNeeded)
- subscribe(location, "sunriseTime", rescheduleIfNeeded)
- subscribe(location, "sunsetTime", rescheduleIfNeeded)
- subscribe(app, appTouch)
-
- //rescheduleIfNeeded()
-}
-
-def appTouch(evt) {
- rescheduleIfNeeded(evt)
- processQueue()
- def queue = []
- atomicState.queue=queue
-}
-
-
-def rescheduleIfNeeded(evt) {
- if (evt) log.debug("rescheduleIfNeeded>$evt.name=$evt.value")
- Integer delay = givenInterval ?: 5 // By default, schedule processQueue every 5 min.
- BigDecimal currentTime = now()
- BigDecimal lastPollTime = (currentTime - (atomicState?.poll["last"]?:0))
- if (lastPollTime != currentTime) {
- Double lastPollTimeInMinutes = (lastPollTime/60000).toDouble().round(1)
- log.info "rescheduleIfNeeded>last poll was ${lastPollTimeInMinutes.toString()} minutes ago"
- }
- if (((atomicState?.poll["last"]?:0) + (delay * 60000) < currentTime) && canSchedule()) {
- log.info "rescheduleIfNeeded>scheduling processQueue in ${delay} minutes.."
- unschedule()
- schedule("14:00", processQueue)
- }
- // Update rescheduled state
-
- if (!evt) {
- atomicState.poll["rescheduled"] = now()
- }
-}
-
-def handleTemperatureEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
-}
-
-def handleHumidityEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
-}
-
-def handleHeatingSetpointEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
-}
-def handleCoolingSetpointEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
-}
-
-def handleThermostatModeEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
-}
-def handleFanModeEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
-}
-def handleHumidifierModeEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
-}
-def handleHumidifierLevelEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
-}
-def handleDehumidifierModeEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
-}
-def handleDehumidifierLevelEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
-}
-def handleVentilatorModeEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
-}
-def handleFanMinOnTimeEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
-}
-def handleVentilatorMinOnTimeEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
-}
-
-def handleThermostatOperatingStateEvent(evt) {
- queueValue(evt) {
- it == "idle" ? 0 : (it == 'fan only') ? 1 : (it == 'heating') ? 2 : 3
- }
-
-}
-def handleDailyStats(evt) {
- queueValue(evt) {
- it.toString()
- }
-
-}
-def handleEquipmentStatusEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
+preferences{
+ section("Select the door lock:") {
+ input "lock1", "capability.lock", required: true
+ }
+ section("Select the door contact sensor:") {
+ input "contact", "capability.contactSensor", required: true
+ }
+ section("Automatically lock the door when closed...") {
+ input "minutesLater", "number", title: "Delay (in minutes):", required: true
+ }
+ section("Automatically unlock the door when open...") {
+ input "secondsLater", "number", title: "Delay (in seconds):", required: true
+ }
+ section( "Notifications" ) {
+ input("recipients", "contact", title: "Send notifications to", required: false) {
+ input "phoneNumber", "phone", title: "Warn with text message (optional)", description: "Phone Number", required: false
+ }
+ }
+}
+
+def installed(){
+ initialize()
+}
+
+def updated(){
+ unsubscribe()
+ unschedule()
+ initialize()
+}
+
+def initialize(){
+ log.debug "Settings: ${settings}"
+ subscribe(lock1, "lock", doorHandler, [filterEvents: false])
+ subscribe(lock1, "unlock", doorHandler, [filterEvents: false])
+ subscribe(contact, "contact.open", doorHandler)
+ subscribe(contact, "contact.closed", doorHandler)
+}
+
+def lockDoor(){
+ log.debug "Locking the door."
+ lock1.lock()
+ if(location.contactBookEnabled) {
+ if ( recipients ) {
+ log.debug ( "Sending Push Notification..." )
+ sendNotificationToContacts( "${lock1} locked after ${contact} was closed for ${minutesLater} minutes!", recipients)
+ }
+ }
+ if (phoneNumber) {
+ log.debug("Sending text message...")
+ sendSms( phoneNumber, "${lock1} locked after ${contact} was closed for ${minutesLater} minutes!")
+ }
+}
+
+def unlockDoor(){
+ log.debug "Unlocking the door."
+ lock1.unlock()
+ if(location.contactBookEnabled) {
+ if ( recipients ) {
+ log.debug ( "Sending Push Notification..." )
+ sendNotificationToContacts( "${lock1} unlocked after ${contact} was opened for ${secondsLater} seconds!", recipients)
+ }
+ }
+ if ( phoneNumber ) {
+ log.debug("Sending text message...")
+ sendSms( phoneNumber, "${lock1} unlocked after ${contact} was opened for ${secondsLater} seconds!")
+ }
+}
+
+def doorHandler(evt){
+ if ((contact.latestValue("contact") == "open") && (evt.value == "locked")) { // If the door is open and a person locks the door then...
+ //def delay = (secondsLater) // runIn uses seconds
+ runIn( secondsLater, unlockDoor ) // ...schedule (in minutes) to unlock... We don't want the door to be closed while the lock is engaged.
+ }
+ else if ((contact.latestValue("contact") == "open") && (evt.value == "unlocked")) { // If the door is open and a person unlocks it then...
+ unschedule( unlockDoor ) // ...we don't need to unlock it later.
+ }
+ else if ((contact.latestValue("contact") == "closed") && (evt.value == "locked")) { // If the door is closed and a person manually locks it then...
+ unschedule( lockDoor ) // ...we don't need to lock it later.
+ }
+ else if ((contact.latestValue("contact") == "closed") && (evt.value == "unlocked")) { // If the door is closed and a person unlocks it then...
+ //def delay = (minutesLater * 60) // runIn uses seconds
+ runIn( (minutesLater * 60), lockDoor ) // ...schedule (in minutes) to lock.
+ }
+ else if ((lock1.latestValue("lock") == "unlocked") && (evt.value == "open")) { // If a person opens an unlocked door...
+ unschedule( lockDoor ) // ...we don't need to lock it later.
+ }
+ else if ((lock1.latestValue("lock") == "unlocked") && (evt.value == "closed")) { // If a person closes an unlocked door...
+ //def delay = (minutesLater * 60) // runIn uses seconds
+ runIn( (minutesLater * 60), lockDoor ) // ...schedule (in minutes) to lock.
+ }
+ else { //Opening or Closing door when locked (in case you have a handle lock)
+ log.debug "Unlocking the door."
+ lock1.unlock()
+ if(location.contactBookEnabled) {
+ if ( recipients ) {
+ log.debug ( "Sending Push Notification..." )
+ sendNotificationToContacts( "${lock1} unlocked after ${contact} was opened or closed when ${lock1} was locked!", recipients)
+ }
+ }
+ if ( phoneNumber ) {
+ log.debug("Sending text message...")
+ sendSms( phoneNumber, "${lock1} unlocked after ${contact} was opened or closed when ${lock1} was locked!")
+ }
+ }
}
-
-def handleProgramNameEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
-}
-
-def handleWaterEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
-}
-def handleSmokeEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
-}
-def handleCarbonMonoxideEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
-}
-
-def handleIlluminanceEvent(evt) {
- log.debug ("handleIlluminanceEvent> $evt.name= $evt.value")
- queueValue(evt) {
- it.toString()
- }
-}
-
-def handleLockEvent(evt) {
- queueValue(evt) {
- it == "locked" ? 1 : 0
- }
-}
-
-def handleBatteryEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
-}
-
-def handleContactEvent(evt) {
- queueValue(evt) {
- it == "open" ? 1 : 0
- }
-}
-
-def handleAccelerationEvent(evt) {
- queueValue(evt) {
- it == "active" ? 1 : 0
- }
-}
-
-def handleMotionEvent(evt) {
- queueValue(evt) {
- it == "active" ? 1 : 0
- }
-}
-
-def handlePresenceEvent(evt) {
- queueValue(evt) {
- it == "present" ? 1 : 0
- }
-}
-
-def handleSwitchEvent(evt) {
- queueValue(evt) {
- it == "on" ? 1 : 0
- }
-}
-
-def handleSetLevelEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
-}
-
-def handlePowerEvent(evt) {
- if (evt.value) {
- queueValue(evt) {
- it.toString()
- }
- }
-}
-
-def handleEnergyEvent(evt) {
- if (evt.value) {
- queueValue(evt) {
- it.toString()
- }
- }
-}
-def handleCostEvent(evt) {
- if (evt.value) {
- queueValue(evt) {
- it.toString()
- }
- }
-}
-
-private queueValue(evt, Closure convert) {
- def MAX_QUEUE_SIZE=95000
- def jsonPayload = [compId: evt.displayName, streamId: evt.name, data: convert(evt.value), time: now()]
- def queue
-
- queue = atomicState.queue
- queue << jsonPayload
- atomicState.queue = queue
- def queue_size = queue.toString().length()
- def last_item_in_queue = queue[queue.size() -1]
- log.debug "queueValue>queue size in chars=${queue_size}, appending ${jsonPayload} to queue, last item in queue= $last_item_in_queue"
- if (queue_size > MAX_QUEUE_SIZE) {
- processQueue()
- }
-}
-
-def processQueue() {
- Integer delay = givenInterval ?: 5 // By default, schedule processQueue every 5 min.
- atomicState?.poll["last"] = now()
-
- if (((atomicState?.poll["rescheduled"]?:0) + (delay * 60000)) < now()) {
- log.info "processQueue>scheduling rescheduleIfNeeded() in ${delay} minutes.."
- schedule("0 0/${delay} * * * ?", rescheduleIfNeeded)
- // Update rescheduled state
- atomicState?.poll["rescheduled"] = now()
- }
-
- def queue = atomicState.queue
-
-
- def url = "https://grovestreams.com/api/feed?api_key=${channelKey}"
- log.debug "processQueue"
- if (queue != []) {
- log.debug "Events to be sent to groveStreams: ${queue}"
-
- /*try {
- httpPutJson([uri: url, body: queue]) {response ->
- if (response.status != 200) {
- log.debug "GroveStreams logging failed, status = ${response.status}"
- } else {
- log.debug "GroveStreams accepted event(s)"
- // reset the queue
- queue =[]
- atomicState.queue = queue
- }
- }
- } catch (groovyx.net.http.ResponseParseException e) {
- // ignore error 200, bogus exception
- if (e.statusCode != 200) {
- log.error "Grovestreams: ${e}"
- } else {
- log.debug "GroveStreams accepted event(s)"
- }
- // reset the queue
- queue =[]
- atomicState.queue = queue
-
- } catch (e) {
- def errorInfo = "Error sending value: ${e}"
- log.error errorInfo
- // reset the queue
- queue =[]
- atomicState.queue = queue
- }*/
- }
-
-}
-
//Global Object for functions in subscribe method!
def initialize = this.&initialize
//Global Object for functions in subscribe method!
-def appTouch = this.&appTouch
+def lockDoor = this.&lockDoor
//Global Object for functions in subscribe method!
-def rescheduleIfNeeded = this.&rescheduleIfNeeded
+def unlockDoor = this.&unlockDoor
//Global Object for functions in subscribe method!
-def handleTemperatureEvent = this.&handleTemperatureEvent
-//Global Object for functions in subscribe method!
-def handleHumidityEvent = this.&handleHumidityEvent
-//Global Object for functions in subscribe method!
-def handleHeatingSetpointEvent = this.&handleHeatingSetpointEvent
-//Global Object for functions in subscribe method!
-def handleCoolingSetpointEvent = this.&handleCoolingSetpointEvent
-//Global Object for functions in subscribe method!
-def handleThermostatModeEvent = this.&handleThermostatModeEvent
-//Global Object for functions in subscribe method!
-def handleFanModeEvent = this.&handleFanModeEvent
-//Global Object for functions in subscribe method!
-def handleHumidifierModeEvent = this.&handleHumidifierModeEvent
-//Global Object for functions in subscribe method!
-def handleHumidifierLevelEvent = this.&handleHumidifierLevelEvent
-//Global Object for functions in subscribe method!
-def handleDehumidifierModeEvent = this.&handleDehumidifierModeEvent
-//Global Object for functions in subscribe method!
-def handleDehumidifierLevelEvent = this.&handleDehumidifierLevelEvent
-//Global Object for functions in subscribe method!
-def handleVentilatorModeEvent = this.&handleVentilatorModeEvent
-//Global Object for functions in subscribe method!
-def handleFanMinOnTimeEvent = this.&handleFanMinOnTimeEvent
-//Global Object for functions in subscribe method!
-def handleVentilatorMinOnTimeEvent = this.&handleVentilatorMinOnTimeEvent
-//Global Object for functions in subscribe method!
-def handleThermostatOperatingStateEvent = this.&handleThermostatOperatingStateEvent
-//Global Object for functions in subscribe method!
-def handleDailyStats = this.&handleDailyStats
-//Global Object for functions in subscribe method!
-def handleEquipmentStatusEvent = this.&handleEquipmentStatusEvent
-//Global Object for functions in subscribe method!
-def handleProgramNameEvent = this.&handleProgramNameEvent
-//Global Object for functions in subscribe method!
-def handleWaterEvent = this.&handleWaterEvent
-//Global Object for functions in subscribe method!
-def handleSmokeEvent = this.&handleSmokeEvent
-//Global Object for functions in subscribe method!
-def handleCarbonMonoxideEvent = this.&handleCarbonMonoxideEvent
-//Global Object for functions in subscribe method!
-def handleIlluminanceEvent = this.&handleIlluminanceEvent
-//Global Object for functions in subscribe method!
-def handleLockEvent = this.&handleLockEvent
-//Global Object for functions in subscribe method!
-def handleBatteryEvent = this.&handleBatteryEvent
-//Global Object for functions in subscribe method!
-def handleContactEvent = this.&handleContactEvent
-//Global Object for functions in subscribe method!
-def handleAccelerationEvent = this.&handleAccelerationEvent
-//Global Object for functions in subscribe method!
-def handleMotionEvent = this.&handleMotionEvent
-//Global Object for functions in subscribe method!
-def handlePresenceEvent = this.&handlePresenceEvent
-//Global Object for functions in subscribe method!
-def handleSwitchEvent = this.&handleSwitchEvent
-//Global Object for functions in subscribe method!
-def handleSetLevelEvent = this.&handleSetLevelEvent
-//Global Object for functions in subscribe method!
-def handlePowerEvent = this.&handlePowerEvent
-//Global Object for functions in subscribe method!
-def handleEnergyEvent = this.&handleEnergyEvent
-//Global Object for functions in subscribe method!
-def handleCostEvent = this.&handleCostEvent
-//Global Object for functions in subscribe method!
-def queueValue = this.&queueValue
-//Global Object for functions in subscribe method!
-def processQueue = this.&processQueue
+def doorHandler = this.&doorHandler
-//Object for class temperature measurement!
-def temperatures
-//Object for class thermostat!
-def thermostats
-//Object for class presence sensor!
-def automatic
-//Object for class smoke detector!
-def detectors
-//Object for class humidity measurement!
-def humidities
-//Object for class water sensor!
-def waters
-//Object for class illuminance measurement!
-def illuminances
//Object for class lock!
-def locks
+def lock1
//Object for class contactSensor!
-def contacts
-//Object for class Acceleration Sensor!
-def accelerations
-//Object for class Motion Sensor!
-def motions
-//Object for class presence sensor!
-def presence
-//Object for class switch!
-def switches
-//Object for class switch level!
-def dimmerSwitches
-//Object for class Battery!
-def batteries
-//Object for class power meter!
-def powers
-//Object for class energy meter!
-def energys
-//Global variable for text!
-def channelKey = "This is just a text!"
+def contact
//Global variable for number!
-def givenInterval = 75
+def minutesLater = 48
+//Global variable for number!
+def secondsLater = 55
+//Global variable for contact!
+def recipients = "AJ"
+//Global variable for phone!
+def phoneNumber = 9495379373
-temperatures = obj.temperatureMeasurementObject
-thermostats = obj.thermostatObject
-automatic = obj.presenceSensorObject
-detectors = obj.smokeDetectorObject
-humidities = obj.humidityMeasurementObject
-waters = obj.waterSensorObject
-illuminances = obj.illuminanceMeasurementObject
-locks = obj.lockObject
-contacts = obj.contactObject
-accelerations = obj.accelerationSensorObject
-motions = obj.motionSensorObject
-presence = obj.presenceSensorObject
-switches = obj.switchObject
-dimmerSwitches = obj.switchLevelObject
-batteries = obj.batteryObject
-powers = obj.powerMeterObject
-energys = obj.energyMeterObject
+lock1 = obj.lockObject
+contact = obj.contactObject
//Global variable for settings!
-settings = [app:app, temperatures:temperatures, thermostats:thermostats, automatic:automatic, detectors:detectors, humidities:humidities, waters:waters, illuminances:illuminances, locks:locks, contacts:contacts, accelerations:accelerations, motions:motions, presence:presence, switches:switches, dimmerSwitches:dimmerSwitches, batteries:batteries, powers:powers, energys:energys, channelKey:channelKey, givenInterval:givenInterval]
+settings = [app:app, lock1:lock1, contact:contact, minutesLater:minutesLater, secondsLater:secondsLater, recipients:recipients, phoneNumber:phoneNumber]
/**
- * Notify If Left Unlocked
+ * Beacon Control
*
- * Copyright 2014 George Sudarkoff
+ * Copyright 2014 Physical Graph Corporation
*
* 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:
* for the specific language governing permissions and limitations under the License.
*
*/
-
definition(
- name: "Notify If Left Unlocked",
- namespace: "com.sudarkoff",
- author: "George Sudarkoff",
- description: "Send a push or SMS notification (and lock, if it's closed) if a door is left unlocked for a period of time.",
- category: "Safety & Security",
- iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
- iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png")
-
+ name: "Beacon Control",
+ category: "SmartThings Internal",
+ namespace: "smartthings",
+ author: "SmartThings",
+ description: "Execute a Hello, Home phrase, turn on or off some lights, and/or lock or unlock your door when you enter or leave a monitored region",
+ iconUrl: "https://s3.amazonaws.com/smartapp-icons/MiscHacking/mindcontrol.png",
+ iconX2Url: "https://s3.amazonaws.com/smartapp-icons/MiscHacking/mindcontrol@2x.png"
+)
preferences {
- section("If this lock...") {
- input "aLock", "capability.lock", multiple: false, required: true
- input "openSensor", "capability.contactSensor", title: "Open/close sensor (optional)", multiple: false, required: false
- }
- section("Left unlocked for...") {
- input "duration", "number", title: "How many minutes?", required: true
- }
- section("Notify me...") {
- input "pushNotification", "bool", title: "Push notification"
- input "phoneNumber", "phone", title: "Phone number (optional)", required: false
- input "lockIfClosed", "bool", title: "Lock the door if it's closed?"
- }
-}
-
-def installed()
-{
- initialize()
-}
-
-def updated()
-{
- unsubscribe()
- initialize()
-}
-
-def initialize()
-{
- log.trace "Initializing with: ${settings}"
- subscribe(aLock, "lock", lockHandler)
-}
-
-def lockHandler(evt)
-{
- log.trace "${evt.name} is ${evt.value}."
- if (evt.value == "locked") {
- log.debug "Canceling lock check because the door is locked..."
- unschedule(notifyUnlocked)
- }
- else {
- log.debug "Starting the countdown for ${duration} minutes..."
- state.retries = 0
- runIn(duration * 60, notifyUnlocked)
- }
-}
-
-def notifyUnlocked()
-{
- // if no open/close sensor specified, assume the door is closed
- def open = openSensor?.latestValue("contact") ?: "closed"
-
- def message = "${aLock.displayName} is left unlocked and ${open} for more than ${duration} minutes."
- log.trace "Sending the notification: ${message}."
- sendMessage(message)
-
- if (lockIfClosed) {
- if (open == "closed") {
- log.trace "And locking the door."
- sendMessage("Locking the ${aLock.displayName} as prescribed.")
- aLock.lock()
- }
- else {
- if (state.retries++ < 3) {
- log.trace "Door is open, can't lock. Rescheduling the check."
- sendMessage("Can't lock the ${aLock.displayName} because the door is open. Will try again in ${duration} minutes.")
- runIn(duration * 60, notifyUnlocked)
+ page(name: "timeIntervalInput", title: "Only during a certain time") {
+ section {
+ input "starting", "time", title: "Starting", required: false
+ input "ending", "time", title: "Ending", required: false
+ }
+ }
+
+ page(name: "mainPage")
+}
+
+def mainPage() {
+ dynamicPage(name: "mainPage", install: true, uninstall: true) {
+
+ section("Where do you want to watch?") {
+ input name: "beacons", type: "capability.beacon", title: "Select your beacon(s)",
+ multiple: true, required: true
+ }
+
+ section("Who do you want to watch for?") {
+ input name: "phones", type: "device.mobilePresence", title: "Select your phone(s)",
+ multiple: true, required: true
+ }
+
+ section("What do you want to do on arrival?") {
+ input name: "arrivalPhrase", type: "enum", title: "Execute a phrase",
+ options: listPhrases(), required: false
+ input "arrivalOnSwitches", "capability.switch", title: "Turn on some switches",
+ multiple: true, required: false
+ input "arrivalOffSwitches", "capability.switch", title: "Turn off some switches",
+ multiple: true, required: false
+ input "arrivalLocks", "capability.lock", title: "Unlock the door",
+ multiple: true, required: false
+ }
+
+ section("What do you want to do on departure?") {
+ input name: "departPhrase", type: "enum", title: "Execute a phrase",
+ options: listPhrases(), required: false
+ input "departOnSwitches", "capability.switch", title: "Turn on some switches",
+ multiple: true, required: false
+ input "departOffSwitches", "capability.switch", title: "Turn off some switches",
+ multiple: true, required: false
+ input "departLocks", "capability.lock", title: "Lock the door",
+ multiple: true, required: false
+ }
+
+ section("Do you want to be notified?") {
+ input "pushNotification", "bool", title: "Send a push notification"
+ input "phone", "phone", title: "Send a text message", description: "Tap to enter phone number",
+ required: false
+ }
+
+ section {
+ label title: "Give your automation a name", description: "e.g. Goodnight Home, Wake Up"
+ }
+
+ def timeLabel = timeIntervalLabel()
+ section(title: "More options", hidden: hideOptionsSection(), hideable: true) {
+ href "timeIntervalInput", title: "Only during a certain time",
+ description: timeLabel ?: "Tap to set", state: timeLabel ? "complete" : "incomplete"
+
+ input "days", "enum", title: "Only on certain days of the week", multiple: true, required: false,
+ options: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
+
+ input "modes", "mode", title: "Only when mode is", multiple: true, required: false
+ }
+ }
+}
+
+// Lifecycle management
+def installed() {
+ log.debug "<beacon-control> Installed with settings: ${settings}"
+ initialize()
+}
+
+def updated() {
+ log.debug "<beacon-control> Updated with settings: ${settings}"
+ unsubscribe()
+ initialize()
+}
+
+def initialize() {
+ subscribe(beacons, "presence", beaconHandler)
+}
+
+// Event handlers
+def beaconHandler(evt) {
+ log.debug "<beacon-control> beaconHandler: $evt"
+
+ if (allOk) {
+ def data = new groovy.json.JsonSlurper().parseText(evt.data)
+ // removed logging of device names. can be added back for debugging
+ //log.debug "<beacon-control> data: $data - phones: " + phones*.deviceNetworkId
+
+ def beaconName = getBeaconName(evt)
+ // removed logging of device names. can be added back for debugging
+ //log.debug "<beacon-control> beaconName: $beaconName"
+
+ def phoneName = getPhoneName(data)
+ // removed logging of device names. can be added back for debugging
+ //log.debug "<beacon-control> phoneName: $phoneName"
+ if (phoneName != null) {
+ def action = data.presence == "1" ? "arrived" : "left"
+ def msg = "$phoneName has $action ${action == 'arrived' ? 'at ' : ''}the $beaconName"
+
+ if (action == "arrived") {
+ msg = arriveActions(msg)
+ }
+ else if (action == "left") {
+ msg = departActions(msg)
}
- else {
- log.trace "The door is still open after ${state.retries} retries, giving up."
- sendMessage("Unable to lock the ${aLock.displayName} after ${state.retries} retries, giving up.")
+ log.debug "<beacon-control> msg: $msg"
+
+ if (pushNotification || phone) {
+ def options = [
+ method: (pushNotification && phone) ? "both" : (pushNotification ? "push" : "sms"),
+ phone: phone
+ ]
+ sendNotification(msg, options)
}
}
- }
+ }
}
-def sendMessage(msg) {
- if (pushNotification) {
- sendPush(msg)
- }
- if (phoneNumber) {
- sendSMS(phoneNumber, msg)
- }
+// Helpers
+private arriveActions(msg) {
+ if (arrivalPhrase || arrivalOnSwitches || arrivalOffSwitches || arrivalLocks) msg += ", so"
+
+ if (arrivalPhrase) {
+ log.debug "<beacon-control> executing: $arrivalPhrase"
+ executePhrase(arrivalPhrase)
+ msg += " ${prefix('executed')} $arrivalPhrase."
+ }
+ if (arrivalOnSwitches) {
+ log.debug "<beacon-control> turning on: $arrivalOnSwitches"
+ arrivalOnSwitches.on()
+ msg += " ${prefix('turned')} ${list(arrivalOnSwitches)} on."
+ }
+ if (arrivalOffSwitches) {
+ log.debug "<beacon-control> turning off: $arrivalOffSwitches"
+ arrivalOffSwitches.off()
+ msg += " ${prefix('turned')} ${list(arrivalOffSwitches)} off."
+ }
+ if (arrivalLocks) {
+ log.debug "<beacon-control> unlocking: $arrivalLocks"
+ arrivalLocks.unlock()
+ msg += " ${prefix('unlocked')} ${list(arrivalLocks)}."
+ }
+ msg
}
+private departActions(msg) {
+ if (departPhrase || departOnSwitches || departOffSwitches || departLocks) msg += ", so"
+
+ if (departPhrase) {
+ log.debug "<beacon-control> executing: $departPhrase"
+ executePhrase(departPhrase)
+ msg += " ${prefix('executed')} $departPhrase."
+ }
+ if (departOnSwitches) {
+ log.debug "<beacon-control> turning on: $departOnSwitches"
+ departOnSwitches.on()
+ msg += " ${prefix('turned')} ${list(departOnSwitches)} on."
+ }
+ if (departOffSwitches) {
+ log.debug "<beacon-control> turning off: $departOffSwitches"
+ departOffSwitches.off()
+ msg += " ${prefix('turned')} ${list(departOffSwitches)} off."
+ }
+ if (departLocks) {
+ log.debug "<beacon-control> unlocking: $departLocks"
+ departLocks.lock()
+ msg += " ${prefix('locked')} ${list(departLocks)}."
+ }
+ msg
+}
+
+private prefix(word) {
+ def result
+ def index = settings.prefixIndex == null ? 0 : settings.prefixIndex + 1
+ switch (index) {
+ case 0:
+ result = "I $word"
+ break
+ case 1:
+ result = "I also $word"
+ break
+ case 2:
+ result = "And I $word"
+ break
+ default:
+ result = "And $word"
+ break
+ }
+
+ settings.prefixIndex = index
+ log.trace "prefix($word'): $result"
+ result
+}
+
+private listPhrases() {
+ location.helloHome.getPhrases().label
+}
+
+private executePhrase(phraseName) {
+ if (phraseName) {
+ location.helloHome.execute(phraseName)
+ log.debug "<beacon-control> executed phrase: $phraseName"
+ }
+}
+
+private getBeaconName(evt) {
+ def beaconName = beacons.find { b -> b.id == evt.deviceId }
+ return beaconName
+}
+
+private getPhoneName(data) {
+ def phoneName = phones.find { phone ->
+ // Work around DNI bug in data
+ def pParts = phone.deviceNetworkId.split('\\|')
+ def dParts = data.dni.split('\\|')
+ pParts[0] == dParts[0]
+ }
+ return phoneName
+}
+
+private hideOptionsSection() {
+ (starting || ending || days || modes) ? false : true
+}
+
+private getAllOk() {
+ modeOk && daysOk && timeOk
+}
+
+private getModeOk() {
+ def result = !modes || modes.contains(location.mode)
+ log.trace "<beacon-control> modeOk = $result"
+ result
+}
+
+private getDaysOk() {
+ def result = true
+ if (days) {
+ def df = new java.text.SimpleDateFormat("EEEE")
+ if (location.timeZone) {
+ df.setTimeZone(location.timeZone)
+ }
+ else {
+ df.setTimeZone(TimeZone.getTimeZone("America/New_York"))
+ }
+ def day = df.format(new Date())
+ result = days.contains(day)
+ }
+ log.trace "<beacon-control> daysOk = $result"
+ result
+}
+
+private getTimeOk() {
+ def result = true
+ if (starting && ending) {
+ def currTime = now()
+ def start = timeToday(starting, location?.timeZone).time
+ def stop = timeToday(ending, location?.timeZone).time
+ result = start < stop ? currTime >= start && currTime <= stop : currTime <= stop || currTime >= start
+ }
+ log.trace "<beacon-control> timeOk = $result"
+ result
+}
+
+private hhmm(time, fmt = "h:mm a") {
+ def t = timeToday(time, location.timeZone)
+ def f = new java.text.SimpleDateFormat(fmt)
+ f.setTimeZone(location.timeZone ?: timeZone(time))
+ f.format(t)
+}
+
+private timeIntervalLabel() {
+ (starting && ending) ? hhmm(starting) + "-" + hhmm(ending, "h:mm a z") : ""
+}
+
+private list(Object names) {
+ return names[0]
+}
//Global Object for functions in subscribe method!
+def mainPage = this.&mainPage
+//Global Object for functions in subscribe method!
def installed = this.&installed
//Global Object for functions in subscribe method!
def updated = this.&updated
//Global Object for functions in subscribe method!
def initialize = this.&initialize
//Global Object for functions in subscribe method!
-def lockHandler = this.&lockHandler
+def beaconHandler = this.&beaconHandler
+//Global Object for functions in subscribe method!
+def arriveActions = this.&arriveActions
+//Global Object for functions in subscribe method!
+def departActions = this.&departActions
+//Global Object for functions in subscribe method!
+def prefix = this.&prefix
+//Global Object for functions in subscribe method!
+def listPhrases = this.&listPhrases
+//Global Object for functions in subscribe method!
+def executePhrase = this.&executePhrase
+//Global Object for functions in subscribe method!
+def getBeaconName = this.&getBeaconName
+//Global Object for functions in subscribe method!
+def getPhoneName = this.&getPhoneName
+//Global Object for functions in subscribe method!
+def hideOptionsSection = this.&hideOptionsSection
+//Global Object for functions in subscribe method!
+def getAllOk = this.&getAllOk
+//Global Object for functions in subscribe method!
+def getModeOk = this.&getModeOk
+//Global Object for functions in subscribe method!
+def getDaysOk = this.&getDaysOk
+//Global Object for functions in subscribe method!
+def getTimeOk = this.&getTimeOk
+//Global Object for functions in subscribe method!
+def hhmm = this.&hhmm
//Global Object for functions in subscribe method!
-def notifyUnlocked = this.¬ifyUnlocked
+def timeIntervalLabel = this.&timeIntervalLabel
//Global Object for functions in subscribe method!
-def sendMessage = this.&sendMessage
+def list = this.&list
+//Global variable for time!
+def starting = "15:00"
+//Global variable for time!
+def ending = "15:00"
+//Object for class beacon sensor!
+def beacons
+//Object for class mobile presence!
+def phones
+//Global variable for enum!
+def arrivalPhrase = "Good Night!"
+//Object for class switch!
+def arrivalOnSwitches
+//Object for class switch!
+def arrivalOffSwitches
//Object for class lock!
-def aLock
-//Object for class contactSensor!
-def openSensor
-//Global variable for number!
-def duration = 47
+def arrivalLocks
+//Global variable for enum!
+def departPhrase = "Good Night!"
+//Object for class switch!
+def departOnSwitches
+//Object for class switch!
+def departOffSwitches
+//Object for class lock!
+def departLocks
//Global variable for boolean!
def pushNotification = "0"
//Global variable for phone!
-def phoneNumber = 9495379373
-//Global variable for boolean!
-def lockIfClosed = "1"
+def phone = 9495379373
+//Global variable for enum!
+def days = "Monday"
+//Global variable for mode!
+def modes = "away"
-aLock = obj.lockObject
-openSensor = obj.contactObject
+beacons = obj.beaconSensorObject
+phones = obj.mobilePresenceObject
+arrivalOnSwitches = obj.switchObject
+arrivalOffSwitches = obj.switchObject
+arrivalLocks = obj.lockObject
+departOnSwitches = obj.switchObject
+departOffSwitches = obj.switchObject
+departLocks = obj.lockObject
//Global variable for settings!
-settings = [app:app, aLock:aLock, openSensor:openSensor, duration:duration, pushNotification:pushNotification, phoneNumber:phoneNumber, lockIfClosed:lockIfClosed]
+settings = [app:app, starting:starting, ending:ending, beacons:beacons, phones:phones, arrivalPhrase:arrivalPhrase, arrivalOnSwitches:arrivalOnSwitches, arrivalOffSwitches:arrivalOffSwitches, arrivalLocks:arrivalLocks, departPhrase:departPhrase, departOnSwitches:departOnSwitches, departOffSwitches:departOffSwitches, departLocks:departLocks, pushNotification:pushNotification, phone:phone, days:days, modes:modes]
/**
- * Notify If Left Unlocked
+ * Beacon Control
*
- * Copyright 2014 George Sudarkoff
+ * Copyright 2014 Physical Graph Corporation
*
* 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:
* for the specific language governing permissions and limitations under the License.
*
*/
-
definition(
- name: "Notify If Left Unlocked",
- namespace: "com.sudarkoff",
- author: "George Sudarkoff",
- description: "Send a push or SMS notification (and lock, if it's closed) if a door is left unlocked for a period of time.",
- category: "Safety & Security",
- iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
- iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png")
-
+ name: "Beacon Control",
+ category: "SmartThings Internal",
+ namespace: "smartthings",
+ author: "SmartThings",
+ description: "Execute a Hello, Home phrase, turn on or off some lights, and/or lock or unlock your door when you enter or leave a monitored region",
+ iconUrl: "https://s3.amazonaws.com/smartapp-icons/MiscHacking/mindcontrol.png",
+ iconX2Url: "https://s3.amazonaws.com/smartapp-icons/MiscHacking/mindcontrol@2x.png"
+)
preferences {
- section("If this lock...") {
- input "aLock", "capability.lock", multiple: false, required: true
- input "openSensor", "capability.contactSensor", title: "Open/close sensor (optional)", multiple: false, required: false
- }
- section("Left unlocked for...") {
- input "duration", "number", title: "How many minutes?", required: true
- }
- section("Notify me...") {
- input "pushNotification", "bool", title: "Push notification"
- input "phoneNumber", "phone", title: "Phone number (optional)", required: false
- input "lockIfClosed", "bool", title: "Lock the door if it's closed?"
- }
+ page(name: "timeIntervalInput", title: "Only during a certain time") {
+ section {
+ input "starting", "time", title: "Starting", required: false
+ input "ending", "time", title: "Ending", required: false
+ }
+ }
+
+ page(name: "mainPage")
}
-def installed()
-{
- initialize()
+def mainPage() {
+ dynamicPage(name: "mainPage", install: true, uninstall: true) {
+
+ section("Where do you want to watch?") {
+ input name: "beacons", type: "capability.beacon", title: "Select your beacon(s)",
+ multiple: true, required: true
+ }
+
+ section("Who do you want to watch for?") {
+ input name: "phones", type: "device.mobilePresence", title: "Select your phone(s)",
+ multiple: true, required: true
+ }
+
+ section("What do you want to do on arrival?") {
+ input name: "arrivalPhrase", type: "enum", title: "Execute a phrase",
+ options: listPhrases(), required: false
+ input "arrivalOnSwitches", "capability.switch", title: "Turn on some switches",
+ multiple: true, required: false
+ input "arrivalOffSwitches", "capability.switch", title: "Turn off some switches",
+ multiple: true, required: false
+ input "arrivalLocks", "capability.lock", title: "Unlock the door",
+ multiple: true, required: false
+ }
+
+ section("What do you want to do on departure?") {
+ input name: "departPhrase", type: "enum", title: "Execute a phrase",
+ options: listPhrases(), required: false
+ input "departOnSwitches", "capability.switch", title: "Turn on some switches",
+ multiple: true, required: false
+ input "departOffSwitches", "capability.switch", title: "Turn off some switches",
+ multiple: true, required: false
+ input "departLocks", "capability.lock", title: "Lock the door",
+ multiple: true, required: false
+ }
+
+ section("Do you want to be notified?") {
+ input "pushNotification", "bool", title: "Send a push notification"
+ input "phone", "phone", title: "Send a text message", description: "Tap to enter phone number",
+ required: false
+ }
+
+ section {
+ label title: "Give your automation a name", description: "e.g. Goodnight Home, Wake Up"
+ }
+
+ def timeLabel = timeIntervalLabel()
+ section(title: "More options", hidden: hideOptionsSection(), hideable: true) {
+ href "timeIntervalInput", title: "Only during a certain time",
+ description: timeLabel ?: "Tap to set", state: timeLabel ? "complete" : "incomplete"
+
+ input "days", "enum", title: "Only on certain days of the week", multiple: true, required: false,
+ options: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
+
+ input "modes", "mode", title: "Only when mode is", multiple: true, required: false
+ }
+ }
}
-def updated()
-{
- unsubscribe()
- initialize()
+// Lifecycle management
+def installed() {
+ log.debug "<beacon-control> Installed with settings: ${settings}"
+ initialize()
}
-def initialize()
-{
- log.trace "Initializing with: ${settings}"
- subscribe(aLock, "lock", lockHandler)
+def updated() {
+ log.debug "<beacon-control> Updated with settings: ${settings}"
+ unsubscribe()
+ initialize()
}
-def lockHandler(evt)
-{
- log.trace "${evt.name} is ${evt.value}."
- if (evt.value == "locked") {
- log.debug "Canceling lock check because the door is locked..."
- unschedule(notifyUnlocked)
- }
- else {
- log.debug "Starting the countdown for ${duration} minutes..."
- state.retries = 0
- runIn(duration * 60, notifyUnlocked)
- }
+def initialize() {
+ subscribe(beacons, "presence", beaconHandler)
}
-def notifyUnlocked()
-{
- // if no open/close sensor specified, assume the door is closed
- def open = openSensor?.latestValue("contact") ?: "closed"
+// Event handlers
+def beaconHandler(evt) {
+ log.debug "<beacon-control> beaconHandler: $evt"
- def message = "${aLock.displayName} is left unlocked and ${open} for more than ${duration} minutes."
- log.trace "Sending the notification: ${message}."
- sendMessage(message)
+ if (allOk) {
+ def data = new groovy.json.JsonSlurper().parseText(evt.data)
+ // removed logging of device names. can be added back for debugging
+ //log.debug "<beacon-control> data: $data - phones: " + phones*.deviceNetworkId
- if (lockIfClosed) {
- if (open == "closed") {
- log.trace "And locking the door."
- sendMessage("Locking the ${aLock.displayName} as prescribed.")
- aLock.lock()
- }
- else {
- if (state.retries++ < 3) {
- log.trace "Door is open, can't lock. Rescheduling the check."
- sendMessage("Can't lock the ${aLock.displayName} because the door is open. Will try again in ${duration} minutes.")
- runIn(duration * 60, notifyUnlocked)
+ def beaconName = getBeaconName(evt)
+ // removed logging of device names. can be added back for debugging
+ //log.debug "<beacon-control> beaconName: $beaconName"
+
+ def phoneName = getPhoneName(data)
+ // removed logging of device names. can be added back for debugging
+ //log.debug "<beacon-control> phoneName: $phoneName"
+ if (phoneName != null) {
+ def action = data.presence == "1" ? "arrived" : "left"
+ def msg = "$phoneName has $action ${action == 'arrived' ? 'at ' : ''}the $beaconName"
+
+ if (action == "arrived") {
+ msg = arriveActions(msg)
}
- else {
- log.trace "The door is still open after ${state.retries} retries, giving up."
- sendMessage("Unable to lock the ${aLock.displayName} after ${state.retries} retries, giving up.")
+ else if (action == "left") {
+ msg = departActions(msg)
+ }
+ log.debug "<beacon-control> msg: $msg"
+
+ if (pushNotification || phone) {
+ def options = [
+ method: (pushNotification && phone) ? "both" : (pushNotification ? "push" : "sms"),
+ phone: phone
+ ]
+ sendNotification(msg, options)
}
}
- }
+ }
+}
+
+// Helpers
+private arriveActions(msg) {
+ if (arrivalPhrase || arrivalOnSwitches || arrivalOffSwitches || arrivalLocks) msg += ", so"
+
+ if (arrivalPhrase) {
+ log.debug "<beacon-control> executing: $arrivalPhrase"
+ executePhrase(arrivalPhrase)
+ msg += " ${prefix('executed')} $arrivalPhrase."
+ }
+ if (arrivalOnSwitches) {
+ log.debug "<beacon-control> turning on: $arrivalOnSwitches"
+ arrivalOnSwitches.on()
+ msg += " ${prefix('turned')} ${list(arrivalOnSwitches)} on."
+ }
+ if (arrivalOffSwitches) {
+ log.debug "<beacon-control> turning off: $arrivalOffSwitches"
+ arrivalOffSwitches.off()
+ msg += " ${prefix('turned')} ${list(arrivalOffSwitches)} off."
+ }
+ if (arrivalLocks) {
+ log.debug "<beacon-control> unlocking: $arrivalLocks"
+ arrivalLocks.unlock()
+ msg += " ${prefix('unlocked')} ${list(arrivalLocks)}."
+ }
+ msg
+}
+
+private departActions(msg) {
+ if (departPhrase || departOnSwitches || departOffSwitches || departLocks) msg += ", so"
+
+ if (departPhrase) {
+ log.debug "<beacon-control> executing: $departPhrase"
+ executePhrase(departPhrase)
+ msg += " ${prefix('executed')} $departPhrase."
+ }
+ if (departOnSwitches) {
+ log.debug "<beacon-control> turning on: $departOnSwitches"
+ departOnSwitches.on()
+ msg += " ${prefix('turned')} ${list(departOnSwitches)} on."
+ }
+ if (departOffSwitches) {
+ log.debug "<beacon-control> turning off: $departOffSwitches"
+ departOffSwitches.off()
+ msg += " ${prefix('turned')} ${list(departOffSwitches)} off."
+ }
+ if (departLocks) {
+ log.debug "<beacon-control> unlocking: $departLocks"
+ departLocks.lock()
+ msg += " ${prefix('locked')} ${list(departLocks)}."
+ }
+ msg
+}
+
+private prefix(word) {
+ def result
+ def index = settings.prefixIndex == null ? 0 : settings.prefixIndex + 1
+ switch (index) {
+ case 0:
+ result = "I $word"
+ break
+ case 1:
+ result = "I also $word"
+ break
+ case 2:
+ result = "And I $word"
+ break
+ default:
+ result = "And $word"
+ break
+ }
+
+ settings.prefixIndex = index
+ log.trace "prefix($word'): $result"
+ result
}
-def sendMessage(msg) {
- if (pushNotification) {
- sendPush(msg)
- }
- if (phoneNumber) {
- sendSMS(phoneNumber, msg)
- }
+private listPhrases() {
+ location.helloHome.getPhrases().label
}
+private executePhrase(phraseName) {
+ if (phraseName) {
+ location.helloHome.execute(phraseName)
+ log.debug "<beacon-control> executed phrase: $phraseName"
+ }
+}
+
+private getBeaconName(evt) {
+ def beaconName = beacons.find { b -> b.id == evt.deviceId }
+ return beaconName
+}
+
+private getPhoneName(data) {
+ def phoneName = phones.find { phone ->
+ // Work around DNI bug in data
+ def pParts = phone.deviceNetworkId.split('\\|')
+ def dParts = data.dni.split('\\|')
+ pParts[0] == dParts[0]
+ }
+ return phoneName
+}
+
+private hideOptionsSection() {
+ (starting || ending || days || modes) ? false : true
+}
+
+private getAllOk() {
+ modeOk && daysOk && timeOk
+}
+
+private getModeOk() {
+ def result = !modes || modes.contains(location.mode)
+ log.trace "<beacon-control> modeOk = $result"
+ result
+}
+
+private getDaysOk() {
+ def result = true
+ if (days) {
+ def df = new java.text.SimpleDateFormat("EEEE")
+ if (location.timeZone) {
+ df.setTimeZone(location.timeZone)
+ }
+ else {
+ df.setTimeZone(TimeZone.getTimeZone("America/New_York"))
+ }
+ def day = df.format(new Date())
+ result = days.contains(day)
+ }
+ log.trace "<beacon-control> daysOk = $result"
+ result
+}
+
+private getTimeOk() {
+ def result = true
+ if (starting && ending) {
+ def currTime = now()
+ def start = timeToday(starting, location?.timeZone).time
+ def stop = timeToday(ending, location?.timeZone).time
+ result = start < stop ? currTime >= start && currTime <= stop : currTime <= stop || currTime >= start
+ }
+ log.trace "<beacon-control> timeOk = $result"
+ result
+}
+
+private hhmm(time, fmt = "h:mm a") {
+ def t = timeToday(time, location.timeZone)
+ def f = new java.text.SimpleDateFormat(fmt)
+ f.setTimeZone(location.timeZone ?: timeZone(time))
+ f.format(t)
+}
+
+private timeIntervalLabel() {
+ (starting && ending) ? hhmm(starting) + "-" + hhmm(ending, "h:mm a z") : ""
+}
+
+private list(Object names) {
+ return names[0]
+}
--- /dev/null
+///////////
+name of event:
+"battery"
+used in:
+'Battery class' + 'Smoke detector class'
+///////////
+name of event:
+"presence"
+used in:
+'Beacon sensor class' + 'Presence sensor class'
+///////////
+name of event:
+"carbonMonoxide"
+used in:
+'Carbon monoxide class' + 'Smoke detector class'
+///////////
+name of event:
+"contact"
+used in:
+'Contact sensor class' + 'Valve class'
+///////////
+name of event:
+"level"
+used in:
+'Switch level class' + 'Music player class'
+///////////
+name of event:
+"on"
+used in:
+'Switch class' + 'Relay switch class'
+///////////
+name of event:
+"off"
+used in:
+'Switch class' + 'Relay switch class'
+///////////
+name of event:
+"temperature"
+used in:
+'Temperature measurement class' + 'Thermostat class'
+///////////
+name of event:
+"switch"
+used in:
+'Switches class' + 'Switch level class' + 'Relay switch class'
+
//By Apps
def setLevel(int level) {
- println("the switch with id:$id is setted to level $level!")
- this.currentLevel = level
+ if (this.currentLevel != level) {
+ println("the switch with id:$id is setted to level $level!")
+ this.currentLevel = level
+ sendEvent([name: "level", value: "40", deviceId: this.id, descriptionText: "",
+ displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+ }
}
def on() {
private String id
private String label
private String displayName
+ private String switchState
+ private String currentSwitch
private int level
private int rate
+ private String switchLatestValue
def sendEvent
def timers
- SwitchLevel(Closure sendEvent, String id, String label, String displayName, int level) {
+ SwitchLevel(Closure sendEvent, String id, String label, String displayName, int level, String switchState, String switchLatestValue) {
this.sendEvent = sendEvent
this.timers = new SimulatedTimer()
this.id = id
this.displayName = displayName
this.level = level
this.rate = level
+ this.switchState = switchState
+ this.currentSwitch = switchState
+ this.switchLatestValue = switchLatestValue
}
//By Apps
}
}
+ def on() {
+ if (this.switchState != "on") {
+ println("the switch with id:$id is on!")
+ this.switchLatestValue = this.switchState
+ this.switchState = "on"
+ this.currentSwitch = "on"
+ sendEvent([name: "switch", value: "on", deviceId: this.id, descriptionText: "",
+ displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+ }
+ }
+
+ def on(LinkedHashMap metaData) {
+ if (this.switchState != "on") {
+ def task = timers.runAfter(metaData["delay"]) {
+ println("the switch with id:$id is on!")
+ this.switchLatestValue = this.switchState
+ this.switchState = "on"
+ this.currentSwitch = "on"
+ sendEvent([name: "switch", value: "on", deviceId: this.id, descriptionText: "",
+ displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+ }
+ }
+ }
+
+ def off() {
+ if (this.switchState != "off") {
+ println("the switch with id:$id is off!")
+ this.switchLatestValue = this.switchState
+ this.switchState = "off"
+ this.currentSwitch = "off"
+ sendEvent([name: "switch", value: "off", deviceId: this.id, descriptionText: "",
+ displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+ }
+ }
+
+ def off(LinkedHashMap metaData) {
+ if (this.switchState != "off") {
+ def task = timers.runAfter(metaData["delay"]) {
+ println("the switch with id:$id is off!")
+ this.switchLatestValue = this.switchState
+ this.switchState = "off"
+ this.currentSwitch = "off"
+ sendEvent([name: "switch", value: "off", deviceId: this.id, descriptionText: "",
+ displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+ }
+ }
+ }
+
//By Model Checker
def setValue(String value) {
println("the switch with id:$id is setted to level $value!")
private String displayName = "switchLevel0"
private int level = 50
private int rate = 50
+ private String switchState = "off"
+ private String currentSwitch = "off"
+ private String switchLatestValue = "off"
SwitchLevels(Closure sendEvent, int deviceNumbers) {
this.sendEvent = sendEvent
this.deviceNumbers = deviceNumbers
this.switchLevels = []
- switchLevels.add(new SwitchLevel(sendEvent, id, label, displayName, this.level))
+ switchLevels.add(new SwitchLevel(sendEvent, id, label, displayName, this.level, this.switchState, this.switchLatestValue))
}
//Methods for closures
}
}
+ def on() {
+ switchLevels[0].on()
+ switchLatestValue = switchState
+ switchState = "on"
+ currentSwitch = "on"
+ }
+
+ def on(LinkedHashMap metaData) {
+ def task = timers.runAfter(metaData["delay"]) {
+ switchLevels[0].on()
+ switchLatestValue = switchState
+ switchState = "on"
+ currentSwitch = "on"
+ }
+ }
+
+ def off() {
+ switchLevels[0].off()
+ switchLatestValue = switchState
+ switchState = "off"
+ currentSwitch = "off"
+ }
+
+ def off(LinkedHashMap metaData) {
+ def task = timers.runAfter(metaData["delay"]) {
+ switchLevels[0].off()
+ switchLatestValue = switchState
+ switchState = "off"
+ currentSwitch = "off"
+ }
+ }
+
//By Model Checker
def setValue(LinkedHashMap eventDataMap) {
if (eventDataMap["value"] != switchLevels[0].level) {
String currentAlarm or String alarm
/*events*/
alarmObject.setValue([name: "alarm", value: "both", deviceId: "alarmID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
alarmObject.setValue([name: "alarm", value: "siren", deviceId: "alarmID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
alarmObject.setValue([name: "alarm", value: "strobe", deviceId: "alarmID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
alarmObject.setValue([name: "alarm", value: "off", deviceId: "alarmID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/*events*/
//
-------------------------------------------------------------------------------
/*events*/
/////
contactObject.setValue([name: "contact.closed", value: "closed", deviceId: "contactSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
contactObject.setValue([name: "contact.open", value: "open", deviceId: "contactSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+contactObject.setValue([name: "contact", value: "open", deviceId: "contactSensorID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+contactObject.setValue([name: "contact", value: "closed", deviceId: "contactSensorID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/////
/*events*/
//
String doorState
/*events*/
doorControlObject.setValue([name: "doorState", value: "closed", deviceId: "doorControlID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
doorControlObject.setValue([name: "doorState", value: "open", deviceId: "doorControlID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/////
/*events*/
//
String location.mode
/*events*/
locationObject.setValue([name: "Location", value: "away", deviceId: "locationID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
locationObject.setValue([name: "Location", value: "home", deviceId: "locationID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
locationObject.setValue([name: "Location", value: "night", deviceId: "locationID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+locationObject.setValue([name: "mode", value: "away", deviceId: "locationID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+locationObject.setValue([name: "mode", value: "home", deviceId: "locationID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+locationObject.setValue([name: "mode", value: "night", deviceId: "locationID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/*events*/
//
-------------------------------------------------------------------------------
String currentLock or String lockState
/*events*/
lockObject.setValue([name: "lock", value: "locked", deviceId: "lockID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
lockObject.setValue([name: "unlock", value: "unlocked ", deviceId: "lockID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+lockObject.setValue([name: "lock", value: "unlocked", deviceId: "lockID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/////
/*events*/
//
String currentMotion or String motion
/*events*/
motionSensorObject.setValue([name: "motion", value: "active", deviceId: "motionSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
motionSensorObject.setValue([name: "motion", value: "inactive", deviceId: "motionSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/////
/*events*/
//
String mute
/*events*/
musicPlayerObject.setValue([name: "status", value: "playing", deviceId: "musicPlayerID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
musicPlayerObject.setValue([name: "status", value: "stopped", deviceId: "musicPlayerID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
musicPlayerObject.setValue([name: "status", value: "paused", deviceId: "musicPlayerID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
musicPlayerObject.setValue([name: "level", value: "36"/*A number between 0 to 100 as a charge*/, deviceId: "musicPlayerID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
musicPlayerObject.setValue([name: "trackDescription", value: "someDescriptions", deviceId: "musicPlayerID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
musicPlayerObject.setValue([name: "trackData", value: "someTrack", deviceId: "musicPlayerID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
-musicPlayerObject.setValue([name: "mute", value: "umuted", deviceId: "musicPlayerID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+musicPlayerObject.setValue([name: "mute", value: "unmuted", deviceId: "musicPlayerID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
musicPlayerObject.setValue([name: "mute", value: "muted", deviceId: "musicPlayerID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/*events*/
//
-------------------------------------------------------------------------------
String currentPresence or String presenceState
/*events*/
presenceSensorObject.setValue([name: "presence", value: "present", deviceId: "presenceSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"presence":"1","dni":"mobile0"}'])
presenceSensorObject.setValue([name: "presence", value: "not present", deviceId: "presenceSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"presence":"0","dni":"mobile0"}'])
+presenceSensorObject.setValue([name: "presence.present", value: "present", deviceId: "presenceSensorID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"presence":"1","dni":"mobile0"}'])
/////
/*events*/
//
String currentSmokeValue or String smoke
/*events*/
smokeDetectorObject.setValue([name: "smoke", value: "clear", deviceId: "smokeDetectorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
smokeDetectorObject.setValue([name: "smoke", value: "detected", deviceId: "smokeDetectorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
smokeDetectorObject.setValue([name: "smoke", value: "tested", deviceId: "smokeDetectorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
smokeDetectorObject.setValue([name: "carbonMonoxide", value: "clear", deviceId: "smokeDetectorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
smokeDetectorObject.setValue([name: "carbonMonoxide", value: "detected", deviceId: "smokeDetectorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
smokeDetectorObject.setValue([name: "carbonMonoxide", value: "tested", deviceId: "smokeDetectorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
smokeDetectorObject.setValue([name: "battery", value: "5"/*A number between 0 to 100 as a charge*/, deviceId: "smokeDetectorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/////
/*events*/
//
String thermostatMode or currentThermostatMode //mode
/*events*/
thermostatObject.setValue([name: "thermostatMode", value: "auto", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
thermostatObject.setValue([name: "thermostatMode", value: "cool", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
thermostatObject.setValue([name: "thermostatMode", value: "emergencyHeat", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
thermostatObject.setValue([name: "thermostatMode", value: "heat", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
thermostatObject.setValue([name: "thermostatMode", value: "off", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
thermostatObject.setValue([name: "temperature", value: "55", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
thermostatObject.setValue([name: "heatingSetpoint", value: "40", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
thermostatObject.setValue([name: "coolingSetpoint", value: "60", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
thermostatObject.setValue([name: "thermostatSetpoint", value: "50", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
thermostatObject.setValue([name: "thermostatFanMode", value: "auto", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
thermostatObject.setValue([name: "thermostatFanMode", value: "fanCirculate", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
thermostatObject.setValue([name: "thermostatFanMode", value: "circulate", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
thermostatObject.setValue([name: "thermostatFanMode", value: "fanOn", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
thermostatObject.setValue([name: "thermostatFanMode", value: "on", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
-thermostatObject.setValue([name: "thermostatOperatingState", value: "auto", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
-thermostatObject.setValue([name: "thermostatOperatingState", value: "cool", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
-thermostatObject.setValue([name: "thermostatOperatingState", value: "off", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
-thermostatObject.setValue([name: "thermostatOperatingState", value: "emergencyHeat", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
-thermostatObject.setValue([name: "thermostatOperatingState", value: "heat", deviceId: "thermostatID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+thermostatObject.setValue([name: "fanMode", value: "auto", deviceId: "thermostatID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+thermostatObject.setValue([name: "fanMode", value: "fanCirculate", deviceId: "thermostatID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+thermostatObject.setValue([name: "fanMode", value: "circulate", deviceId: "thermostatID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+thermostatObject.setValue([name: "fanMode", value: "fanOn", deviceId: "thermostatID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+thermostatObject.setValue([name: "fanMode", value: "on", deviceId: "thermostatID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+thermostatObject.setValue([name: "thermostatOperatingState", value: "cooling", deviceId: "thermostatID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+thermostatObject.setValue([name: "thermostatOperatingState", value: "fan only", deviceId: "thermostatID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+thermostatObject.setValue([name: "thermostatOperatingState", value: "heating", deviceId: "thermostatID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+thermostatObject.setValue([name: "thermostatOperatingState", value: "idle", deviceId: "thermostatID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+thermostatObject.setValue([name: "thermostatOperatingState", value: "pending cool", deviceId: "thermostatID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+thermostatObject.setValue([name: "thermostatOperatingState", value: "pending heat", deviceId: "thermostatID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+thermostatObject.setValue([name: "thermostatOperatingState", value: "vent economizer", deviceId: "thermostatID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/////
/*events*/
//
String currentSwitch or switchState
/*events*/
switchObject.setValue([name: "switch", value: "off", deviceId: "switchID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
switchObject.setValue([name: "switch", value: "on", deviceId: "switchID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/////
/*events*/
//
//For appTouch:
/*events*/
appObject.setValue([name: "Touched", value: "touched", deviceId: "touchedSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/////
/*events*/
//
//For nfcTouch:
/*events*/
touchSensorObject.setValue([name: "nfcTouch", value: "touched", deviceId: "nfcSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/////
/*events*/
//
//For aeonKeyFob push button:
/*events*/
aeonKeyFobObject.setValue([name: "button", value: "pushed", deviceId: "aeonKeyFobID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
aeonKeyFobObject.setValue([name: "button", value: "held", deviceId: "aeonKeyFobID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/////
/////
/*events*/
String currentAcceleration or String acceleration
/*events*/
accelerationSensorObject.setValue([name: "acceleration", value: "active", deviceId: "accelerationSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
accelerationSensorObject.setValue([name: "acceleration", value: "inactive", deviceId: "accelerationSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/////
/*events*/
//
int currentBattery or int battery
/*events*/
batteryObject.setValue([name: "battery", value: "50"/*number between 0 to 100 as a string*/, deviceId: "batteryID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/*events*/
//
-------------------------------------------------------------------------------
//For beacon sensor:
String currentPresence or String presence
/*events*/
-beaconSensorObject.setValue([name: "beacon", value: "present", deviceId: "beaconeSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
-beaconSensorObject.setValue([name: "beacon", value: "not present", deviceId: "beaconSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+beaconSensorObject.setValue([name: "presence", value: "present", deviceId: "beaconeSensorID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"presence":"1","dni":"mobile0"}'])
+beaconSensorObject.setValue([name: "presence", value: "not present", deviceId: "beaconSensorID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"presence":"0","dni":"mobile0"}'])
/////
/*events*/
//
String currentCarbonMonoxideValue or String carbonMonoxide
/*events*/
carbonMonoxideDetectorObject.setValue([name: "carbonMonoxide", value: "clear", deviceId: "carbonMonoxideDetectorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
carbonMonoxideDetectorObject.setValue([name: "carbonMonoxide", value: "detected", deviceId: "carbonMonoxideDetectorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
carbonMonoxideDetectorObject.setValue([name: "carbonMonoxide", value: "tested", deviceId: "carbonMonoxideDetectorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/*events*/
//
-------------------------------------------------------------------------------
int saturation
/*events*/
colorControlObject.setValue([name: "color", value: "red", deviceId: "colorControlID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
colorControlObject.setValue([name: "hue", value: "50", deviceId: "colorControlID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
colorControlObject.setValue([name: "saturation", value: "50", deviceId: "colorControlID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/*events*/
//
-------------------------------------------------------------------------------
int energy or int currentEnergy
/*events*/
energyMeterObject.setValue([name: "energy", value: "45"/*A number between 0 to 100 as a charge*/, deviceId: "energyMeterID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/*events*/
//
-------------------------------------------------------------------------------
int illuminance or int currentIlluminance
/*events*/
illuminanceMeasurementObject.setValue([name: "illuminance", value: "70"/*A number between 0 to 100 as a charge*/, deviceId: "illuminanceMeasurementID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/*events*/
//
-------------------------------------------------------------------------------
int power or int currentPower
/*events*/
powerMeterObject.setValue([name: "power", value: "70"/*A number between 0 to 100 as a charge*/, deviceId: "powerMeterID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/*events*/
//
-------------------------------------------------------------------------------
int humidity or int currentHumidity
/*events*/
humidityMeasurementObject.setValue([name: "humidity", value: "70"/*A number between 0 to 100 as a charge*/, deviceId: "humidityMeasurementID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/*events*/
//
-------------------------------------------------------------------------------
//For relay switches:
String currentSwitch or switchState
/*events*/
-switchObject.setValue([name: "switch", value: "off", deviceId: "relaySwitchID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
-switchObject.setValue([name: "switch", value: "on", deviceId: "relaySwitchID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+relaySwitchObject.setValue([name: "switch", value: "off", deviceId: "relaySwitchID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+relaySwitchObject.setValue([name: "switch", value: "on", deviceId: "relaySwitchID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/////
/*events*/
//
String sleeping
/*events*/
sleepSensorObject.setValue([name: "sleeping", value: "sleeping", deviceId: "sleepSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
sleepSensorObject.setValue([name: "sleeping", value: "not sleeping", deviceId: "sleepSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/////
/*events*/
//
int steps
/*events*/
stepSensorObject.setValue([name: "goal", value: "100"/*A number*/, deviceId: "stepSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
stepSensorObject.setValue([name: "steps", value: "46"/*A number*/, deviceId: "stepSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/////
/*events*/
//
int level or int rate
/*events*/
switchLevelObject.setValue([name: "level", value: "45"/*A number between 0 to 100*/, deviceId: "switchLevelID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+switchLevelObject.setValue([name: "switch", value: "on", deviceId: "switchLevelID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
+switchLevelObject.setValue([name: "switch", value: "off", deviceId: "switchLevelID0", descriptionText: "",
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/////
/*events*/
//
int temperature
/*events*/
temperatureMeasurementObject.setValue([name: "temperature", value: "45"/*A number between 0 to 100*/, deviceId: "temperatureMeasurementID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/////
/*events*/
//
String valve
/*events*/
valveObject.setValue([name: "contact", value: "closed", deviceId: "valveID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
valveObject.setValue([name: "contact", value: "open", deviceId: "valveID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/////
/*events*/
//
String water
/*events*/
waterSensorObject.setValue([name: "water", value: "dry", deviceId: "waterSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
waterSensorObject.setValue([name: "water", value: "wet", deviceId: "waterSensorID0", descriptionText: "",
-displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]])
+displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
/////
/*events*/
//
while(true) {
- def eventNumber = Verify.getInt(0,53)
+ def eventNumber = Verify.getInt(0,4)
switch(eventNumber) {
case 0:
+ lockObject.setValue([name: "lock", value: "locked", deviceId: "lockID0", descriptionText: "",
+ displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
break
case 1:
+ lockObject.setValue([name: "unlock", value: "unlocked ", deviceId: "lockID0", descriptionText: "",
+ displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
break
case 2:
+ contactObject.setValue([name: "contact.open", value: "open", deviceId: "contactSensorID0", descriptionText: "",
+ displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
break
case 3:
- def event = Verify.getInt(0,2)
- if (event == 0) {
- smokeDetectorObject.setValue([name: "smoke", value: "clear", deviceId: "smokeDetectorID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else if (event == 1) {
- smokeDetectorObject.setValue([name: "smoke", value: "detected", deviceId: "smokeDetectorID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else {
- smokeDetectorObject.setValue([name: "smoke", value: "tested", deviceId: "smokeDetectorID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- }
- break
- case 4:
- def event = Verify.getInt(0,2)
- if (event == 0) {
- smokeDetectorObject.setValue([name: "carbonMonoxide", value: "clear", deviceId: "smokeDetectorID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else if (event == 1) {
- smokeDetectorObject.setValue([name: "carbonMonoxide", value: "detected", deviceId: "smokeDetectorID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else {
- smokeDetectorObject.setValue([name: "carbonMonoxide", value: "tested", deviceId: "smokeDetectorID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- }
- break
- case 5:
- break
- case 6:
- break
- case 7:
- lockObject.setValue([name: "lock", value: "locked", deviceId: "lockID0", descriptionText: "",
+ contactObject.setValue([name: "contact.closed", value: "closed", deviceId: "contactSensorID0", descriptionText: "",
displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
break
- case 8:
- def event = Verify.getInt(0,1)
- if (event == 0) {
- accelerationSensorObject.setValue([name: "acceleration", value: "active", deviceId: "accelerationSensorID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else {
- accelerationSensorObject.setValue([name: "acceleration", value: "inactive", deviceId: "accelerationSensorID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- }
- break
- case 9:
- def event = Verify.getInt(0,1)
- if (event == 0) {
- motionSensorObject.setValue([name: "motion", value: "active", deviceId: "motionSensorID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else {
- motionSensorObject.setValue([name: "motion", value: "inactive", deviceId: "motionSensorID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- }
- break
- case 10:
+ case 4:
def event = Verify.getInt(0,1)
if (event == 0) {
presenceSensorObject.setValue([name: "presence", value: "present", deviceId: "presenceSensorID0", descriptionText: "",
displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"presence":"0","dni":"mobile0"}'])
}
break
- case 11:
- def event = Verify.getInt(0,1)
- if (event == 0) {
- switchObject.setValue([name: "switch", value: "on", deviceId: "switchID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else {
- switchObject.setValue([name: "switch", value: "off", deviceId: "switchID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- }
- break
- case 12:
- break
- case 13:
- smokeDetectorObject.setValue([name: "battery", value: "5", deviceId: "smokeDetectorID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- break
- case 14:
- break
- case 15:
- break
- case 16:
- break
- case 17:
- break
- case 18:
- break
- case 19:
- def event = Verify.getInt(0,4)
- if (event == 0) {
- thermostatObject.setValue([name: "thermostatMode", value: "auto", deviceId: "thermostatID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else if (event == 1) {
- thermostatObject.setValue([name: "thermostatMode", value: "cool", deviceId: "thermostatID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else if (event == 2) {
- thermostatObject.setValue([name: "thermostatMode", value: "emergencyHeat", deviceId: "thermostatID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else if (event == 3) {
- thermostatObject.setValue([name: "thermostatMode", value: "heat", deviceId: "thermostatID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else {
- thermostatObject.setValue([name: "thermostatMode", value: "off", deviceId: "thermostatID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- }
- break
- case 20:
- break
- case 21:
- break
- case 22:
- break
- case 23:
- break
- case 24:
- break
- case 25:
- break
- case 26:
- break
- case 27:
- break
- case 28:
- break
- case 29:
- break
- case 30:
- break
- case 31:
- break
- case 32:
- break
- case 33:
- break
- case 34:
- break
- case 35:
- break
- case 36:
- break
- case 37:
- break
- case 38:
- break
- case 39:
- break
- case 40:
- break
- case 41:
- break
- case 42:
- break
- case 43:
- break
- case 44:
- break
- case 45:
- break
- case 46:
- break
- case 47:
- break
- case 48:
- break
- case 49:
- break
- case 50:
- break
- case 51:
- break
- case 52:
- def event = Verify.getInt(0,2)
- if (event == 0) {
- locationObject.setValue([name: "Location", value: "home", deviceId: "locationID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else if (event == 1) {
- locationObject.setValue([name: "Location", value: "away", deviceId: "locationID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else {
- locationObject.setValue([name: "Location", value: "night", deviceId: "locationID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- }
- break
- case 53:
- appObject.setValue([name: "Touched", value: "touched", deviceId: "touchedSensorID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- break
}
}
def atomicState
//Extracted objects for App1
- //Object for class temperature measurement!
- def temperatures
- //Object for class thermostat!
- def thermostats
- //Object for class presence sensor!
- def automatic
- //Object for class smoke detector!
- def detectors
- //Object for class humidity measurement!
- def humidities
- //Object for class water sensor!
- def waters
- //Object for class illuminance measurement!
- def illuminances
//Object for class lock!
- def locks
+ def lock1
//Object for class contactSensor!
- def contacts
- //Object for class Acceleration Sensor!
- def accelerations
- //Object for class Motion Sensor!
- def motions
- //Object for class presence sensor!
- def presence
- //Object for class switch!
- def switches
- //Object for class switch level!
- def dimmerSwitches
- //Object for class Battery!
- def batteries
- //Object for class power meter!
- def powers
- //Object for class energy meter!
- def energys
- //Global variable for text!
- def channelKey = "This is just a text!"
+ def contact
+ //Global variable for number!
+ def minutesLater = 48
//Global variable for number!
- def givenInterval = 75
+ def secondsLater = 55
+ //Global variable for contact!
+ def recipients = "AJ"
+ //Global variable for phone!
+ def phoneNumber = 9495379373
//Extracted objects for functions for App1
//Global Object for functions in subscribe method!
//Global Object for functions in subscribe method!
def initialize = this.&initialize
//Global Object for functions in subscribe method!
- def appTouch = this.&appTouch
- //Global Object for functions in subscribe method!
- def rescheduleIfNeeded = this.&rescheduleIfNeeded
- //Global Object for functions in subscribe method!
- def handleTemperatureEvent = this.&handleTemperatureEvent
- //Global Object for functions in subscribe method!
- def handleHumidityEvent = this.&handleHumidityEvent
- //Global Object for functions in subscribe method!
- def handleHeatingSetpointEvent = this.&handleHeatingSetpointEvent
- //Global Object for functions in subscribe method!
- def handleCoolingSetpointEvent = this.&handleCoolingSetpointEvent
- //Global Object for functions in subscribe method!
- def handleThermostatModeEvent = this.&handleThermostatModeEvent
- //Global Object for functions in subscribe method!
- def handleFanModeEvent = this.&handleFanModeEvent
- //Global Object for functions in subscribe method!
- def handleHumidifierModeEvent = this.&handleHumidifierModeEvent
- //Global Object for functions in subscribe method!
- def handleHumidifierLevelEvent = this.&handleHumidifierLevelEvent
- //Global Object for functions in subscribe method!
- def handleDehumidifierModeEvent = this.&handleDehumidifierModeEvent
- //Global Object for functions in subscribe method!
- def handleDehumidifierLevelEvent = this.&handleDehumidifierLevelEvent
- //Global Object for functions in subscribe method!
- def handleVentilatorModeEvent = this.&handleVentilatorModeEvent
- //Global Object for functions in subscribe method!
- def handleFanMinOnTimeEvent = this.&handleFanMinOnTimeEvent
- //Global Object for functions in subscribe method!
- def handleVentilatorMinOnTimeEvent = this.&handleVentilatorMinOnTimeEvent
- //Global Object for functions in subscribe method!
- def handleThermostatOperatingStateEvent = this.&handleThermostatOperatingStateEvent
- //Global Object for functions in subscribe method!
- def handleDailyStats = this.&handleDailyStats
- //Global Object for functions in subscribe method!
- def handleEquipmentStatusEvent = this.&handleEquipmentStatusEvent
- //Global Object for functions in subscribe method!
- def handleProgramNameEvent = this.&handleProgramNameEvent
+ def lockDoor = this.&lockDoor
//Global Object for functions in subscribe method!
- def handleWaterEvent = this.&handleWaterEvent
+ def unlockDoor = this.&unlockDoor
//Global Object for functions in subscribe method!
- def handleSmokeEvent = this.&handleSmokeEvent
- //Global Object for functions in subscribe method!
- def handleCarbonMonoxideEvent = this.&handleCarbonMonoxideEvent
- //Global Object for functions in subscribe method!
- def handleIlluminanceEvent = this.&handleIlluminanceEvent
- //Global Object for functions in subscribe method!
- def handleLockEvent = this.&handleLockEvent
- //Global Object for functions in subscribe method!
- def handleBatteryEvent = this.&handleBatteryEvent
- //Global Object for functions in subscribe method!
- def handleContactEvent = this.&handleContactEvent
- //Global Object for functions in subscribe method!
- def handleAccelerationEvent = this.&handleAccelerationEvent
- //Global Object for functions in subscribe method!
- def handleMotionEvent = this.&handleMotionEvent
- //Global Object for functions in subscribe method!
- def handlePresenceEvent = this.&handlePresenceEvent
- //Global Object for functions in subscribe method!
- def handleSwitchEvent = this.&handleSwitchEvent
- //Global Object for functions in subscribe method!
- def handleSetLevelEvent = this.&handleSetLevelEvent
- //Global Object for functions in subscribe method!
- def handlePowerEvent = this.&handlePowerEvent
- //Global Object for functions in subscribe method!
- def handleEnergyEvent = this.&handleEnergyEvent
- //Global Object for functions in subscribe method!
- def handleCostEvent = this.&handleCostEvent
- //Global Object for functions in subscribe method!
- def queueValue = this.&queueValue
- //Global Object for functions in subscribe method!
- def processQueue = this.&processQueue
+ def doorHandler = this.&doorHandler
App1(Object obj) {
reference = obj
location = obj.locationObject
app = obj.appObject
atomicState = obj.atomicState
- temperatures = obj.temperatureMeasurementObject
- thermostats = obj.thermostatObject
- automatic = obj.presenceSensorObject
- detectors = obj.smokeDetectorObject
- humidities = obj.humidityMeasurementObject
- waters = obj.waterSensorObject
- illuminances = obj.illuminanceMeasurementObject
- locks = obj.lockObject
- contacts = obj.contactObject
- accelerations = obj.accelerationSensorObject
- motions = obj.motionSensorObject
- presence = obj.presenceSensorObject
- switches = obj.switchObject
- dimmerSwitches = obj.switchLevelObject
- batteries = obj.batteryObject
- powers = obj.powerMeterObject
- energys = obj.energyMeterObject
+ lock1 = obj.lockObject
+ contact = obj.contactObject
//Global variable for settings!
- settings = [app:app, temperatures:temperatures, thermostats:thermostats, automatic:automatic, detectors:detectors, humidities:humidities, waters:waters, illuminances:illuminances, locks:locks, contacts:contacts, accelerations:accelerations, motions:motions, presence:presence, switches:switches, dimmerSwitches:dimmerSwitches, batteries:batteries, powers:powers, energys:energys, channelKey:channelKey, givenInterval:givenInterval]
+ settings = [app:app, lock1:lock1, contact:contact, minutesLater:minutesLater, secondsLater:secondsLater, recipients:recipients, phoneNumber:phoneNumber]
}
//Global variables for each app
//Global variable for state[mode]
return true
}
- def installed() {
- initialize()
- }
-
- def updated() {
- unsubscribe()
- unschedule()
- initialize()
- }
-
- def initialize() {
- subscribe(temperatures, "temperature", handleTemperatureEvent)
- subscribe(humidities, "humidity", handleHumidityEvent)
- subscribe(waters, "water", handleWaterEvent)
- subscribe(waters, "water", handleWaterEvent)
- subscribe(detectors, "smoke", handleSmokeEvent)
- subscribe(detectors, "carbonMonoxide", handleCarbonMonoxideEvent)
- subscribe(illuminances, "illuminance", handleIlluminanceEvent)
- subscribe(contacts, "contact", handleContactEvent)
- subscribe(locks, "lock", handleLockEvent)
- subscribe(accelerations, "acceleration", handleAccelerationEvent)
- subscribe(motions, "motion", handleMotionEvent)
- subscribe(presence, "presence", handlePresenceEvent)
- subscribe(switches, "switch", handleSwitchEvent)
- subscribe(dimmerSwitches, "switch", handleSwitchEvent)
- subscribe(dimmerSwitches, "level", handleSetLevelEvent)
- subscribe(batteries, "battery", handleBatteryEvent)
- subscribe(powers, "power", handlePowerEvent)
- subscribe(energys, "energy", handleEnergyEvent)
- subscribe(energys, "cost", handleCostEvent)
- subscribe(thermostats, "heatingSetpoint", handleHeatingSetpointEvent)
- subscribe(thermostats, "coolingSetpoint", handleCoolingSetpointEvent)
- subscribe(thermostats, "thermostatMode", handleThermostatModeEvent)
- subscribe(thermostats, "fanMode", handleFanModeEvent)
- subscribe(thermostats, "thermostatOperatingState", handleThermostatOperatingStateEvent)
- /*subscribe(ecobees, "dehumidifierMode", handleDehumidifierModeEvent)
- subscribe(ecobees, "equipmentStatus", handleEquipmentStatusEvent)
- subscribe(ecobees, "dehumidifierLevel", handleDehumidifierLevelEvent)
- subscribe(ecobees, "humidifierMode", handleHumidifierModeEvent)
- subscribe(ecobees, "humidifierLevel", handleHumidifierLevelEvent)
- subscribe(ecobees, "fanMinOnTime", handleFanMinOnTimeEvent)
- subscribe(ecobees, "ventilatorMode", handleVentilatorModeEvent)
- subscribe(ecobees, "ventilatorMinOnTime", handleVentilatorMinOnTimeEvent)
- subscribe(ecobees, "programScheduleName", handleProgramNameEvent)
- subscribe(ecobees, "auxHeat1RuntimeDaily", handleDailyStats)
- subscribe(ecobees, "auxHeat2RuntimeDaily", handleDailyStats)
- subscribe(ecobees, "auxHeat3RuntimeDaily", handleDailyStats)
- subscribe(ecobees, "compCool1RuntimeDaily", handleDailyStats)
- subscribe(ecobees, "compCool2RuntimeDaily", handleDailyStats)
- subscribe(ecobees, "fanRuntimeDaily", handleDailyStats)
- subscribe(ecobees, "humidifierRuntimeDaily", handleDailyStats)
- subscribe(ecobees, "dehumidifierRuntimeDaily", handleDailyStats)
- subscribe(ecobees, "ventilatorRuntimeDaily", handleDailyStats)
- subscribe(ecobees, "presence", handlePresenceEvent)
- subscribe(ecobees, "compCool2RuntimeDaily", handleDailyStats)*/
- subscribe(automatic, "yesterdayTripsAvgAverageKmpl",handleDailyStats)
- subscribe(automatic, "yesterdayTripsAvgDistanceM",handleDailyStats)
- subscribe(automatic, "yesterdayTripsAvgDurationS",handleDailyStats)
- subscribe(automatic, "yesterdayTotalDistanceM",handleDailyStats)
- subscribe(automatic, "yesterdayTripsAvgFuelVolumeL",handleDailyStats)
- subscribe(automatic, "yesterdayTotalFuelVolumeL",handleDailyStats)
- subscribe(automatic, "yesterdayTotalDurationS:",handleDailyStats)
- subscribe(automatic, "yesterdayTotalNbTrips",handleDailyStats)
- subscribe(automatic, "yesterdayTotalHardAccels",handleDailyStats)
- subscribe(automatic, "yesterdayTotalHardBrakes:",handleDailyStats)
- subscribe(automatic, "yesterdayTripsAvgScoreSpeeding",handleDailyStats)
- subscribe(automatic, "yesterdayTripsAvgScoreEvents",handleDailyStats)
- def queue = []
- atomicState.queue=queue
-
- if (atomicState.queue==null) {
- atomicState.queue = []
- }
- atomicState?.poll = [ last: 0, rescheduled: now() ]
-
- Integer delay = givenInterval ?: 5 // By default, schedule processQueue every 5 min.
- log.debug "initialize>scheduling processQueue every ${delay} minutes"
-
- //Subscribe to different events (ex. sunrise and sunset events) to trigger rescheduling if needed
- subscribe(location, "sunrise", rescheduleIfNeeded)
- subscribe(location, "sunset", rescheduleIfNeeded)
- subscribe(location, "mode", rescheduleIfNeeded)
- subscribe(location, "sunriseTime", rescheduleIfNeeded)
- subscribe(location, "sunsetTime", rescheduleIfNeeded)
- subscribe(app, appTouch)
-
- //rescheduleIfNeeded()
- }
-
- def appTouch(evt) {
- rescheduleIfNeeded(evt)
- processQueue()
- def queue = []
- atomicState.queue=queue
- }
-
-
- def rescheduleIfNeeded(evt) {
- if (evt) log.debug("rescheduleIfNeeded>$evt.name=$evt.value")
- Integer delay = givenInterval ?: 5 // By default, schedule processQueue every 5 min.
- BigDecimal currentTime = now()
- BigDecimal lastPollTime = (currentTime - (atomicState?.poll["last"]?:0))
- if (lastPollTime != currentTime) {
- Double lastPollTimeInMinutes = (lastPollTime/60000).toDouble().round(1)
- log.info "rescheduleIfNeeded>last poll was ${lastPollTimeInMinutes.toString()} minutes ago"
- }
- if (((atomicState?.poll["last"]?:0) + (delay * 60000) < currentTime) && canSchedule()) {
- log.info "rescheduleIfNeeded>scheduling processQueue in ${delay} minutes.."
- unschedule()
- schedule("14:00", processQueue)
- }
- // Update rescheduled state
-
- if (!evt) {
- atomicState.poll["rescheduled"] = now()
- }
- }
-
- def handleTemperatureEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
- }
-
- def handleHumidityEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
- }
-
- def handleHeatingSetpointEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
- }
- def handleCoolingSetpointEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
- }
-
- def handleThermostatModeEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
- }
- def handleFanModeEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
- }
- def handleHumidifierModeEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
- }
- def handleHumidifierLevelEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
- }
- def handleDehumidifierModeEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
- }
- def handleDehumidifierLevelEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
- }
- def handleVentilatorModeEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
- }
- def handleFanMinOnTimeEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
- }
- def handleVentilatorMinOnTimeEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
- }
-
- def handleThermostatOperatingStateEvent(evt) {
- queueValue(evt) {
- it == "idle" ? 0 : (it == 'fan only') ? 1 : (it == 'heating') ? 2 : 3
- }
-
- }
- def handleDailyStats(evt) {
- queueValue(evt) {
- it.toString()
- }
-
- }
- def handleEquipmentStatusEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
- }
-
- def handleProgramNameEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
- }
-
- def handleWaterEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
- }
- def handleSmokeEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
- }
- def handleCarbonMonoxideEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
- }
-
- def handleIlluminanceEvent(evt) {
- log.debug ("handleIlluminanceEvent> $evt.name= $evt.value")
- queueValue(evt) {
- it.toString()
- }
- }
-
- def handleLockEvent(evt) {
- queueValue(evt) {
- it == "locked" ? 1 : 0
- }
- }
-
- def handleBatteryEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
- }
-
- def handleContactEvent(evt) {
- queueValue(evt) {
- it == "open" ? 1 : 0
- }
- }
-
- def handleAccelerationEvent(evt) {
- queueValue(evt) {
- it == "active" ? 1 : 0
- }
- }
-
- def handleMotionEvent(evt) {
- queueValue(evt) {
- it == "active" ? 1 : 0
- }
- }
-
- def handlePresenceEvent(evt) {
- queueValue(evt) {
- it == "present" ? 1 : 0
- }
- }
-
- def handleSwitchEvent(evt) {
- queueValue(evt) {
- it == "on" ? 1 : 0
- }
+ def installed(){
+ initialize()
}
- def handleSetLevelEvent(evt) {
- queueValue(evt) {
- it.toString()
- }
+ def updated(){
+ unsubscribe()
+ unschedule()
+ initialize()
}
- def handlePowerEvent(evt) {
- if (evt.value) {
- queueValue(evt) {
- it.toString()
- }
- }
+ def initialize(){
+ log.debug "Settings: ${settings}"
+ subscribe(lock1, "lock", doorHandler, [filterEvents: false])
+ subscribe(lock1, "unlock", doorHandler, [filterEvents: false])
+ subscribe(contact, "contact.open", doorHandler)
+ subscribe(contact, "contact.closed", doorHandler)
}
- def handleEnergyEvent(evt) {
- if (evt.value) {
- queueValue(evt) {
- it.toString()
- }
- }
- }
- def handleCostEvent(evt) {
- if (evt.value) {
- queueValue(evt) {
- it.toString()
- }
- }
+ def lockDoor(){
+ log.debug "Locking the door."
+ lock1.lock()
+ if(location.contactBookEnabled) {
+ if ( recipients ) {
+ log.debug ( "Sending Push Notification..." )
+ sendNotificationToContacts( "${lock1} locked after ${contact} was closed for ${minutesLater} minutes!", recipients)
+ }
+ }
+ if (phoneNumber) {
+ log.debug("Sending text message...")
+ sendSms( phoneNumber, "${lock1} locked after ${contact} was closed for ${minutesLater} minutes!")
+ }
}
- private queueValue(evt, Closure convert) {
- def MAX_QUEUE_SIZE=95000
- def jsonPayload = [compId: evt.displayName, streamId: evt.name, data: convert(evt.value), time: now()]
- def queue
-
- queue = atomicState.queue
- queue << jsonPayload
- atomicState.queue = queue
- def queue_size = queue.toString().length()
- def last_item_in_queue = queue[queue.size() -1]
- log.debug "queueValue>queue size in chars=${queue_size}, appending ${jsonPayload} to queue, last item in queue= $last_item_in_queue"
- if (queue_size > MAX_QUEUE_SIZE) {
- processQueue()
- }
+ def unlockDoor(){
+ log.debug "Unlocking the door."
+ lock1.unlock()
+ if(location.contactBookEnabled) {
+ if ( recipients ) {
+ log.debug ( "Sending Push Notification..." )
+ sendNotificationToContacts( "${lock1} unlocked after ${contact} was opened for ${secondsLater} seconds!", recipients)
+ }
+ }
+ if ( phoneNumber ) {
+ log.debug("Sending text message...")
+ sendSms( phoneNumber, "${lock1} unlocked after ${contact} was opened for ${secondsLater} seconds!")
+ }
}
- def processQueue() {
- Integer delay = givenInterval ?: 5 // By default, schedule processQueue every 5 min.
- atomicState?.poll["last"] = now()
-
- if (((atomicState?.poll["rescheduled"]?:0) + (delay * 60000)) < now()) {
- log.info "processQueue>scheduling rescheduleIfNeeded() in ${delay} minutes.."
- schedule("0 0/${delay} * * * ?", rescheduleIfNeeded)
- // Update rescheduled state
- atomicState?.poll["rescheduled"] = now()
- }
-
- def queue = atomicState.queue
-
-
- def url = "https://grovestreams.com/api/feed?api_key=${channelKey}"
- log.debug "processQueue"
- if (queue != []) {
- log.debug "Events to be sent to groveStreams: ${queue}"
-
- /*try {
- httpPutJson([uri: url, body: queue]) {response ->
- if (response.status != 200) {
- log.debug "GroveStreams logging failed, status = ${response.status}"
- } else {
- log.debug "GroveStreams accepted event(s)"
- // reset the queue
- queue =[]
- atomicState.queue = queue
- }
- }
- } catch (groovyx.net.http.ResponseParseException e) {
- // ignore error 200, bogus exception
- if (e.statusCode != 200) {
- log.error "Grovestreams: ${e}"
- } else {
- log.debug "GroveStreams accepted event(s)"
- }
- // reset the queue
- queue =[]
- atomicState.queue = queue
-
- } catch (e) {
- def errorInfo = "Error sending value: ${e}"
- log.error errorInfo
- // reset the queue
- queue =[]
- atomicState.queue = queue
- }*/
- }
-
+ def doorHandler(evt){
+ if ((contact.latestValue("contact") == "open") && (evt.value == "locked")) { // If the door is open and a person locks the door then...
+ //def delay = (secondsLater) // runIn uses seconds
+ runIn( secondsLater, unlockDoor ) // ...schedule (in minutes) to unlock... We don't want the door to be closed while the lock is engaged.
+ }
+ else if ((contact.latestValue("contact") == "open") && (evt.value == "unlocked")) { // If the door is open and a person unlocks it then...
+ unschedule( unlockDoor ) // ...we don't need to unlock it later.
+ }
+ else if ((contact.latestValue("contact") == "closed") && (evt.value == "locked")) { // If the door is closed and a person manually locks it then...
+ unschedule( lockDoor ) // ...we don't need to lock it later.
+ }
+ else if ((contact.latestValue("contact") == "closed") && (evt.value == "unlocked")) { // If the door is closed and a person unlocks it then...
+ //def delay = (minutesLater * 60) // runIn uses seconds
+ runIn( (minutesLater * 60), lockDoor ) // ...schedule (in minutes) to lock.
+ }
+ else if ((lock1.latestValue("lock") == "unlocked") && (evt.value == "open")) { // If a person opens an unlocked door...
+ unschedule( lockDoor ) // ...we don't need to lock it later.
+ }
+ else if ((lock1.latestValue("lock") == "unlocked") && (evt.value == "closed")) { // If a person closes an unlocked door...
+ //def delay = (minutesLater * 60) // runIn uses seconds
+ runIn( (minutesLater * 60), lockDoor ) // ...schedule (in minutes) to lock.
+ }
+ else { //Opening or Closing door when locked (in case you have a handle lock)
+ log.debug "Unlocking the door."
+ lock1.unlock()
+ if(location.contactBookEnabled) {
+ if ( recipients ) {
+ log.debug ( "Sending Push Notification..." )
+ sendNotificationToContacts( "${lock1} unlocked after ${contact} was opened or closed when ${lock1} was locked!", recipients)
+ }
+ }
+ if ( phoneNumber ) {
+ log.debug("Sending text message...")
+ sendSms( phoneNumber, "${lock1} unlocked after ${contact} was opened or closed when ${lock1} was locked!")
+ }
+ }
}
-
}
def atomicState
//Extracted objects for App2
+ //Global variable for time!
+ def starting = "15:00"
+ //Global variable for time!
+ def ending = "15:00"
+ //Object for class beacon sensor!
+ def beacons
+ //Object for class mobile presence!
+ def phones
+ //Global variable for enum!
+ def arrivalPhrase = "Good Night!"
+ //Object for class switch!
+ def arrivalOnSwitches
+ //Object for class switch!
+ def arrivalOffSwitches
//Object for class lock!
- def aLock
- //Object for class contactSensor!
- def openSensor
- //Global variable for number!
- def duration = 47
+ def arrivalLocks
+ //Global variable for enum!
+ def departPhrase = "Good Night!"
+ //Object for class switch!
+ def departOnSwitches
+ //Object for class switch!
+ def departOffSwitches
+ //Object for class lock!
+ def departLocks
//Global variable for boolean!
def pushNotification = "0"
//Global variable for phone!
- def phoneNumber = 9495379373
- //Global variable for boolean!
- def lockIfClosed = "1"
+ def phone = 9495379373
+ //Global variable for enum!
+ def days = "Monday"
+ //Global variable for mode!
+ def modes = "away"
//Extracted objects for functions for App2
//Global Object for functions in subscribe method!
+ def mainPage = this.&mainPage
+ //Global Object for functions in subscribe method!
def installed = this.&installed
//Global Object for functions in subscribe method!
def updated = this.&updated
//Global Object for functions in subscribe method!
def initialize = this.&initialize
//Global Object for functions in subscribe method!
- def lockHandler = this.&lockHandler
+ def beaconHandler = this.&beaconHandler
+ //Global Object for functions in subscribe method!
+ def arriveActions = this.&arriveActions
+ //Global Object for functions in subscribe method!
+ def departActions = this.&departActions
+ //Global Object for functions in subscribe method!
+ def prefix = this.&prefix
//Global Object for functions in subscribe method!
- def notifyUnlocked = this.¬ifyUnlocked
+ def listPhrases = this.&listPhrases
//Global Object for functions in subscribe method!
- def sendMessage = this.&sendMessage
+ def executePhrase = this.&executePhrase
+ //Global Object for functions in subscribe method!
+ def getBeaconName = this.&getBeaconName
+ //Global Object for functions in subscribe method!
+ def getPhoneName = this.&getPhoneName
+ //Global Object for functions in subscribe method!
+ def hideOptionsSection = this.&hideOptionsSection
+ //Global Object for functions in subscribe method!
+ def getAllOk = this.&getAllOk
+ //Global Object for functions in subscribe method!
+ def getModeOk = this.&getModeOk
+ //Global Object for functions in subscribe method!
+ def getDaysOk = this.&getDaysOk
+ //Global Object for functions in subscribe method!
+ def getTimeOk = this.&getTimeOk
+ //Global Object for functions in subscribe method!
+ def hhmm = this.&hhmm
+ //Global Object for functions in subscribe method!
+ def timeIntervalLabel = this.&timeIntervalLabel
+ //Global Object for functions in subscribe method!
+ def list = this.&list
App2(Object obj) {
reference = obj
location = obj.locationObject
app = obj.appObject
atomicState = obj.atomicState
- aLock = obj.lockObject
- openSensor = obj.contactObject
+ beacons = obj.beaconSensorObject
+ phones = obj.mobilePresenceObject
+ arrivalOnSwitches = obj.switchObject
+ arrivalOffSwitches = obj.switchObject
+ arrivalLocks = obj.lockObject
+ departOnSwitches = obj.switchObject
+ departOffSwitches = obj.switchObject
+ departLocks = obj.lockObject
//Global variable for settings!
- settings = [app:app, aLock:aLock, openSensor:openSensor, duration:duration, pushNotification:pushNotification, phoneNumber:phoneNumber, lockIfClosed:lockIfClosed]
+ settings = [app:app, starting:starting, ending:ending, beacons:beacons, phones:phones, arrivalPhrase:arrivalPhrase, arrivalOnSwitches:arrivalOnSwitches, arrivalOffSwitches:arrivalOffSwitches, arrivalLocks:arrivalLocks, departPhrase:departPhrase, departOnSwitches:departOnSwitches, departOffSwitches:departOffSwitches, departLocks:departLocks, pushNotification:pushNotification, phone:phone, days:days, modes:modes]
}
//Global variables for each app
//Global variable for state[mode]
return true
}
- def installed()
- {
- initialize()
+ def mainPage() {
+ dynamicPage(name: "mainPage", install: true, uninstall: true) {
+
+ section("Where do you want to watch?") {
+ input name: "beacons", type: "capability.beacon", title: "Select your beacon(s)",
+ multiple: true, required: true
+ }
+
+ section("Who do you want to watch for?") {
+ input name: "phones", type: "device.mobilePresence", title: "Select your phone(s)",
+ multiple: true, required: true
+ }
+
+ section("What do you want to do on arrival?") {
+ input name: "arrivalPhrase", type: "enum", title: "Execute a phrase",
+ options: listPhrases(), required: false
+ input "arrivalOnSwitches", "capability.switch", title: "Turn on some switches",
+ multiple: true, required: false
+ input "arrivalOffSwitches", "capability.switch", title: "Turn off some switches",
+ multiple: true, required: false
+ input "arrivalLocks", "capability.lock", title: "Unlock the door",
+ multiple: true, required: false
+ }
+
+ section("What do you want to do on departure?") {
+ input name: "departPhrase", type: "enum", title: "Execute a phrase",
+ options: listPhrases(), required: false
+ input "departOnSwitches", "capability.switch", title: "Turn on some switches",
+ multiple: true, required: false
+ input "departOffSwitches", "capability.switch", title: "Turn off some switches",
+ multiple: true, required: false
+ input "departLocks", "capability.lock", title: "Lock the door",
+ multiple: true, required: false
+ }
+
+ section("Do you want to be notified?") {
+ input "pushNotification", "bool", title: "Send a push notification"
+ input "phone", "phone", title: "Send a text message", description: "Tap to enter phone number",
+ required: false
+ }
+
+ section {
+ label title: "Give your automation a name", description: "e.g. Goodnight Home, Wake Up"
+ }
+
+ def timeLabel = timeIntervalLabel()
+ section(title: "More options", hidden: hideOptionsSection(), hideable: true) {
+ href "timeIntervalInput", title: "Only during a certain time",
+ description: timeLabel ?: "Tap to set", state: timeLabel ? "complete" : "incomplete"
+
+ input "days", "enum", title: "Only on certain days of the week", multiple: true, required: false,
+ options: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
+
+ input "modes", "mode", title: "Only when mode is", multiple: true, required: false
+ }
+ }
}
- def updated()
- {
- unsubscribe()
- initialize()
+ // Lifecycle management
+ def installed() {
+ log.debug "<beacon-control> Installed with settings: ${settings}"
+ initialize()
}
- def initialize()
- {
- log.trace "Initializing with: ${settings}"
- subscribe(aLock, "lock", lockHandler)
+ def updated() {
+ log.debug "<beacon-control> Updated with settings: ${settings}"
+ unsubscribe()
+ initialize()
}
- def lockHandler(evt)
- {
- log.trace "${evt.name} is ${evt.value}."
- if (evt.value == "locked") {
- log.debug "Canceling lock check because the door is locked..."
- unschedule(notifyUnlocked)
- }
- else {
- log.debug "Starting the countdown for ${duration} minutes..."
- state.retries = 0
- runIn(duration * 60, notifyUnlocked)
- }
+ def initialize() {
+ subscribe(beacons, "presence", beaconHandler)
}
- def notifyUnlocked()
- {
- // if no open/close sensor specified, assume the door is closed
- def open = openSensor?.latestValue("contact") ?: "closed"
+ // Event handlers
+ def beaconHandler(evt) {
+ log.debug "<beacon-control> beaconHandler: $evt"
- def message = "${aLock.displayName} is left unlocked and ${open} for more than ${duration} minutes."
- log.trace "Sending the notification: ${message}."
- sendMessage(message)
+ if (allOk) {
+ def data = new groovy.json.JsonSlurper().parseText(evt.data)
+ // removed logging of device names. can be added back for debugging
+ //log.debug "<beacon-control> data: $data - phones: " + phones*.deviceNetworkId
- if (lockIfClosed) {
- if (open == "closed") {
- log.trace "And locking the door."
- sendMessage("Locking the ${aLock.displayName} as prescribed.")
- aLock.lock()
- }
- else {
- if (state.retries++ < 3) {
- log.trace "Door is open, can't lock. Rescheduling the check."
- sendMessage("Can't lock the ${aLock.displayName} because the door is open. Will try again in ${duration} minutes.")
- runIn(duration * 60, notifyUnlocked)
+ def beaconName = getBeaconName(evt)
+ // removed logging of device names. can be added back for debugging
+ //log.debug "<beacon-control> beaconName: $beaconName"
+
+ def phoneName = getPhoneName(data)
+ // removed logging of device names. can be added back for debugging
+ //log.debug "<beacon-control> phoneName: $phoneName"
+ if (phoneName != null) {
+ def action = data.presence == "1" ? "arrived" : "left"
+ def msg = "$phoneName has $action ${action == 'arrived' ? 'at ' : ''}the $beaconName"
+
+ if (action == "arrived") {
+ msg = arriveActions(msg)
}
- else {
- log.trace "The door is still open after ${state.retries} retries, giving up."
- sendMessage("Unable to lock the ${aLock.displayName} after ${state.retries} retries, giving up.")
+ else if (action == "left") {
+ msg = departActions(msg)
+ }
+ log.debug "<beacon-control> msg: $msg"
+
+ if (pushNotification || phone) {
+ def options = [
+ method: (pushNotification && phone) ? "both" : (pushNotification ? "push" : "sms"),
+ phone: phone
+ ]
+ sendNotification(msg, options)
}
}
- }
+ }
}
- def sendMessage(msg) {
- if (pushNotification) {
- sendPush(msg)
- }
- if (phoneNumber) {
- sendSMS(phoneNumber, msg)
- }
+ // Helpers
+ private arriveActions(msg) {
+ if (arrivalPhrase || arrivalOnSwitches || arrivalOffSwitches || arrivalLocks) msg += ", so"
+
+ if (arrivalPhrase) {
+ log.debug "<beacon-control> executing: $arrivalPhrase"
+ executePhrase(arrivalPhrase)
+ msg += " ${prefix('executed')} $arrivalPhrase."
+ }
+ if (arrivalOnSwitches) {
+ log.debug "<beacon-control> turning on: $arrivalOnSwitches"
+ arrivalOnSwitches.on()
+ msg += " ${prefix('turned')} ${list(arrivalOnSwitches)} on."
+ }
+ if (arrivalOffSwitches) {
+ log.debug "<beacon-control> turning off: $arrivalOffSwitches"
+ arrivalOffSwitches.off()
+ msg += " ${prefix('turned')} ${list(arrivalOffSwitches)} off."
+ }
+ if (arrivalLocks) {
+ log.debug "<beacon-control> unlocking: $arrivalLocks"
+ arrivalLocks.unlock()
+ msg += " ${prefix('unlocked')} ${list(arrivalLocks)}."
+ }
+ msg
+ }
+
+ private departActions(msg) {
+ if (departPhrase || departOnSwitches || departOffSwitches || departLocks) msg += ", so"
+
+ if (departPhrase) {
+ log.debug "<beacon-control> executing: $departPhrase"
+ executePhrase(departPhrase)
+ msg += " ${prefix('executed')} $departPhrase."
+ }
+ if (departOnSwitches) {
+ log.debug "<beacon-control> turning on: $departOnSwitches"
+ departOnSwitches.on()
+ msg += " ${prefix('turned')} ${list(departOnSwitches)} on."
+ }
+ if (departOffSwitches) {
+ log.debug "<beacon-control> turning off: $departOffSwitches"
+ departOffSwitches.off()
+ msg += " ${prefix('turned')} ${list(departOffSwitches)} off."
+ }
+ if (departLocks) {
+ log.debug "<beacon-control> unlocking: $departLocks"
+ departLocks.lock()
+ msg += " ${prefix('locked')} ${list(departLocks)}."
+ }
+ msg
+ }
+
+ private prefix(word) {
+ def result
+ def index = settings.prefixIndex == null ? 0 : settings.prefixIndex + 1
+ switch (index) {
+ case 0:
+ result = "I $word"
+ break
+ case 1:
+ result = "I also $word"
+ break
+ case 2:
+ result = "And I $word"
+ break
+ default:
+ result = "And $word"
+ break
+ }
+
+ settings.prefixIndex = index
+ log.trace "prefix($word'): $result"
+ result
+ }
+
+ private listPhrases() {
+ location.helloHome.getPhrases().label
+ }
+
+ private executePhrase(phraseName) {
+ if (phraseName) {
+ location.helloHome.execute(phraseName)
+ log.debug "<beacon-control> executed phrase: $phraseName"
+ }
+ }
+
+ private getBeaconName(evt) {
+ def beaconName = beacons.find { b -> b.id == evt.deviceId }
+ return beaconName
+ }
+
+ private getPhoneName(data) {
+ def phoneName = phones.find { phone ->
+ // Work around DNI bug in data
+ def pParts = phone.deviceNetworkId.split('\\|')
+ def dParts = data.dni.split('\\|')
+ pParts[0] == dParts[0]
+ }
+ return phoneName
+ }
+
+ private hideOptionsSection() {
+ (starting || ending || days || modes) ? false : true
+ }
+
+ private getAllOk() {
+ modeOk && daysOk && timeOk
+ }
+
+ private getModeOk() {
+ def result = !modes || modes.contains(location.mode)
+ log.trace "<beacon-control> modeOk = $result"
+ result
+ }
+
+ private getDaysOk() {
+ def result = true
+ if (days) {
+ def df = new java.text.SimpleDateFormat("EEEE")
+ if (location.timeZone) {
+ df.setTimeZone(location.timeZone)
+ }
+ else {
+ df.setTimeZone(TimeZone.getTimeZone("America/New_York"))
+ }
+ def day = df.format(new Date())
+ result = days.contains(day)
+ }
+ log.trace "<beacon-control> daysOk = $result"
+ result
+ }
+
+ private getTimeOk() {
+ def result = true
+ if (starting && ending) {
+ def currTime = now()
+ def start = timeToday(starting, location?.timeZone).time
+ def stop = timeToday(ending, location?.timeZone).time
+ result = start < stop ? currTime >= start && currTime <= stop : currTime <= stop || currTime >= start
+ }
+ log.trace "<beacon-control> timeOk = $result"
+ result
+ }
+
+ private hhmm(time, fmt = "h:mm a") {
+ def t = timeToday(time, location.timeZone)
+ def f = new java.text.SimpleDateFormat(fmt)
+ f.setTimeZone(location.timeZone ?: timeZone(time))
+ f.format(t)
}
+ private timeIntervalLabel() {
+ (starting && ending) ? hhmm(starting) + "-" + hhmm(ending, "h:mm a z") : ""
+ }
+
+ private list(Object names) {
+ return names[0]
+ }
}
@Field def app1
}
while(true) {
- def eventNumber = Verify.getInt(0,53)
+ def eventNumber = Verify.getInt(0,4)
switch(eventNumber) {
case 0:
+ lockObject.setValue([name: "lock", value: "locked", deviceId: "lockID0", descriptionText: "",
+ displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
break
case 1:
+ lockObject.setValue([name: "unlock", value: "unlocked ", deviceId: "lockID0", descriptionText: "",
+ displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
break
case 2:
+ contactObject.setValue([name: "contact.open", value: "open", deviceId: "contactSensorID0", descriptionText: "",
+ displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
break
case 3:
- def event = Verify.getInt(0,2)
- if (event == 0) {
- smokeDetectorObject.setValue([name: "smoke", value: "clear", deviceId: "smokeDetectorID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else if (event == 1) {
- smokeDetectorObject.setValue([name: "smoke", value: "detected", deviceId: "smokeDetectorID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else {
- smokeDetectorObject.setValue([name: "smoke", value: "tested", deviceId: "smokeDetectorID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- }
- break
- case 4:
- def event = Verify.getInt(0,2)
- if (event == 0) {
- smokeDetectorObject.setValue([name: "carbonMonoxide", value: "clear", deviceId: "smokeDetectorID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else if (event == 1) {
- smokeDetectorObject.setValue([name: "carbonMonoxide", value: "detected", deviceId: "smokeDetectorID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else {
- smokeDetectorObject.setValue([name: "carbonMonoxide", value: "tested", deviceId: "smokeDetectorID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- }
- break
- case 5:
- break
- case 6:
- break
- case 7:
- lockObject.setValue([name: "lock", value: "locked", deviceId: "lockID0", descriptionText: "",
+ contactObject.setValue([name: "contact.closed", value: "closed", deviceId: "contactSensorID0", descriptionText: "",
displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
break
- case 8:
- def event = Verify.getInt(0,1)
- if (event == 0) {
- accelerationSensorObject.setValue([name: "acceleration", value: "active", deviceId: "accelerationSensorID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else {
- accelerationSensorObject.setValue([name: "acceleration", value: "inactive", deviceId: "accelerationSensorID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- }
- break
- case 9:
- def event = Verify.getInt(0,1)
- if (event == 0) {
- motionSensorObject.setValue([name: "motion", value: "active", deviceId: "motionSensorID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else {
- motionSensorObject.setValue([name: "motion", value: "inactive", deviceId: "motionSensorID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- }
- break
- case 10:
+ case 4:
def event = Verify.getInt(0,1)
if (event == 0) {
presenceSensorObject.setValue([name: "presence", value: "present", deviceId: "presenceSensorID0", descriptionText: "",
displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"presence":"0","dni":"mobile0"}'])
}
break
- case 11:
- def event = Verify.getInt(0,1)
- if (event == 0) {
- switchObject.setValue([name: "switch", value: "on", deviceId: "switchID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else {
- switchObject.setValue([name: "switch", value: "off", deviceId: "switchID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- }
- break
- case 12:
- break
- case 13:
- smokeDetectorObject.setValue([name: "battery", value: "5", deviceId: "smokeDetectorID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- break
- case 14:
- break
- case 15:
- break
- case 16:
- break
- case 17:
- break
- case 18:
- break
- case 19:
- def event = Verify.getInt(0,4)
- if (event == 0) {
- thermostatObject.setValue([name: "thermostatMode", value: "auto", deviceId: "thermostatID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else if (event == 1) {
- thermostatObject.setValue([name: "thermostatMode", value: "cool", deviceId: "thermostatID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else if (event == 2) {
- thermostatObject.setValue([name: "thermostatMode", value: "emergencyHeat", deviceId: "thermostatID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else if (event == 3) {
- thermostatObject.setValue([name: "thermostatMode", value: "heat", deviceId: "thermostatID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else {
- thermostatObject.setValue([name: "thermostatMode", value: "off", deviceId: "thermostatID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- }
- break
- case 20:
- break
- case 21:
- break
- case 22:
- break
- case 23:
- break
- case 24:
- break
- case 25:
- break
- case 26:
- break
- case 27:
- break
- case 28:
- break
- case 29:
- break
- case 30:
- break
- case 31:
- break
- case 32:
- break
- case 33:
- break
- case 34:
- break
- case 35:
- break
- case 36:
- break
- case 37:
- break
- case 38:
- break
- case 39:
- break
- case 40:
- break
- case 41:
- break
- case 42:
- break
- case 43:
- break
- case 44:
- break
- case 45:
- break
- case 46:
- break
- case 47:
- break
- case 48:
- break
- case 49:
- break
- case 50:
- break
- case 51:
- break
- case 52:
- def event = Verify.getInt(0,2)
- if (event == 0) {
- locationObject.setValue([name: "Location", value: "home", deviceId: "locationID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else if (event == 1) {
- locationObject.setValue([name: "Location", value: "away", deviceId: "locationID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- } else {
- locationObject.setValue([name: "Location", value: "night", deviceId: "locationID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- }
- break
- case 53:
- appObject.setValue([name: "Touched", value: "touched", deviceId: "touchedSensorID0", descriptionText: "",
- displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}'])
- break
}
}