2 * Medicine Management - Temp-Motion
4 * Copyright 2016 Jim Mangione
6 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
7 * in compliance with the License. You may obtain a copy of the License at:
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
12 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
13 * for the specific language governing permissions and limitations under the License.
16 * --- If temp > threshold set, send notification
17 * --- Send in-app notification at the medicine reminder time if no motion is detected in past 60 minutes
18 * --- If motion still isn't detected 10 minutes AFTER reminder time, LED will turn RED
19 * --- ----- Once motion is detected, LED will turn back to it's original color
21 import groovy.time.TimeCategory
24 name: "Medicine Management - Temp-Motion",
25 namespace: "MangioneImagery",
26 author: "Jim Mangione",
27 description: "This only supports devices with capabilities TemperatureMeasurement, AccelerationSensor and ColorControl (LED). Supports two use cases. First, will notifies via in-app if the fridge where meds are stored exceeds a temperature threshold set in degrees. Secondly, sends an in-app and ambient light notification if you forget to take your meds by sensing movement of the medicine box in the fridge. A reminder will be set to a single time per day. If the box isn't moved within 60 minutes of that reminder, an in-app message will be sent. If the box still isn't moved after an additional 10 minutes, then an LED light turns red until the box is moved",
28 category: "Health & Wellness",
29 iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
30 iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
31 iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png")
36 section("My Medicine in the Refrigerator"){
37 input "deviceAccelerationSensor", "capability.accelerationSensor", required: true, multiple: false, title: "Movement"
38 input "deviceTemperatureMeasurement", "capability.temperatureMeasurement", required: true, multiple: false, title: "Temperature"
41 section("Temperature Threshold"){
42 input "tempThreshold", "number", title: "Temperature Threshold"
45 section("Remind me to take my medicine at"){
46 input "reminderTime", "time", title: "Time"
49 // NOTE: Use REAL device - virtual device causes compilation errors
50 section("My LED Light"){
51 input "deviceLight", "capability.colorControl", title: "Smart light"
57 log.debug "Installed with settings: ${settings}"
63 log.debug "Updated with settings: ${settings}"
71 // will notify when temp exceeds max
72 subscribe(deviceTemperatureMeasurement, "temperature", tempHandler)
74 // will stop LED notification incase it was set by med reminder
75 subscribe(deviceAccelerationSensor, "acceleration.active", motionHandler)
77 // how many minutes to look in the past from the reminder time
78 state.minutesToCheckPriorToReminder = 60
80 // Set a timer to run once a day to notify if draw wasn't opened yet
81 schedule(reminderTime, checkMotionInPast)
85 // If temp > 39 then send an app notification out.
87 if (evt.doubleValue > tempThreshold) {
88 log.debug "Fridge temp of $evt.value exceeded threshold"
89 sendNotification("WARNING: Fridge temp is $evt.value with threshold of $tempThreshold")
93 // Should turn off any LED notification once motion detected
94 def motionHandler(evt){
95 // always call out to stop any possible LED notification
96 log.debug "Medication moved. Send stop LED notification"
97 resetLEDNotification()
100 // If no motion detected within 60 minutes of the timer send notification out.
101 def checkMotionInPast(){
102 log.debug "Checking past 60 minutes of activity from $reminderTime"
104 // check activity of sensor for past 60 minutes for any OPENED status
105 def movement = isMoved(state.minutesToCheckPriorToReminder)
106 log.debug "Motion found: $movement"
108 // if there was movement, then do nothing and assume they took their meds
110 sendNotification("Hi, please remember to take your meds in the fridge")
112 // if no movement, send out notification and set new reminder
113 def reminderTimePlus10 = new Date(now() + (10 * 60000))
115 // needs to be scheduled if draw wasn't already opened
116 runOnce(reminderTimePlus10, checkMotionAfterReminder)
120 // If still no movement after 10 minutes past reminder, use LED notification
121 def checkMotionAfterReminder(){
122 log.debug "Checking additional 10 minutes of activity from $reminderTime"
124 // check activity of sensor for past 10 minutes for any OPENED status
125 def movement = isMoved(10)
127 log.debug "Motion found: $movement"
129 // if no open activity, blink lights
131 log.debug "Notify LED API"
137 // Helper function for sending out an app notification
138 def sendNotification(msg){
139 log.debug "Message Sent: $msg"
143 // Check if the accelerometer has been activated since the minutes entered
144 // Return true if active, else false.
145 def isMoved(minutes){
146 // query last X minutes of activity log
147 def previousDateTime = new Date(now() - (minutes * 60000))
149 // capture all events recorded
150 def evts = deviceAccelerationSensor.eventsSince(previousDateTime)
152 if (evts.size() > 0) {
154 if(it.value == "active") {
163 // Saves current color and sets the light to RED
164 def setLEDNotification(){
166 // turn light back off when reset is called if it was originally off
167 state.ledState = deviceLight.currentValue("switch")
169 // set light to RED and store original color until stopped
170 state.origColor = deviceLight.currentValue("hue")
172 deviceLight.setHue(100)
174 log.debug "LED set to RED. Original color stored: $state.origColor"
178 // Sets the color back to the original saved color
179 def resetLEDNotification(){
181 // return color to original
182 log.debug "Reset LED color to: $state.origColor"
183 deviceLight.setHue(state.origColor)
185 // if the light was turned on just for the notification, turn it back off now
186 if (state.ledState == "off") {