MIMOlite Garage Door Sensor with Position Indicator

I wonder if I can use this method with a magnetic contact switch? I am also concerned with missing the open/closed event, but am using this for a gate and cannot use the potentiometer. I would think that the periodic update would tell me the status even though I am not using the input to sig1 as an analog signal with a pot (for instance shorted with contacts closed would give you zero volts and open contacts would be max volts). I am not concerned with actual position, just if it is open or closed. Can someone tell me if this concept will work, I really need accurate gate status?

That’s the original use case for the Mimolite, so yes!

Yes, thanks John. Sorry that I was not specific enough. I realize that I can use the code that you developed with a magnetic switch but I am concerned about missing the trigger event and not knowing the true status of the gate. I wondered if by using the code modified by Simon for use with a pot could also be used with the magnetic contact switch. This would use the MultiLevel Sensor status to periodically read voltage level at SIG1 and therefore get updates every 10 seconds with correct status. I would expect to see max supply voltage or 0 volts, does this make any sense?

Yes this should work. I don’t think you’ll need to make any changes to the code.
Give it a try, if it doesn’t work post the logs from the handler and I’ll see if I can help.

BTW If you had two magnetic sensors, one to detect closed and one to detect open, you could use my device handler to make it work better than with one sensor. The only thing it wont show you is how far it is open when it is not fully open or closed. Are you interested in attaching two sensors to your gate, one for open and one for closed? If so I can draw up a wiring diagram that will work, you’ll also need to buy a couple of resistors so that the mmioLite can tell the two magnetic sensors apart, it isn’t a very difficult wiring job.

1 Like

Thanks Simon, I will try this out in a week or so since this is at my vacation property. I am not sure I will be able to use two sensors for this application due to the way I am using it. This is kind of a unique application. The gate is powered by solar and is about 1000 feet away from the cabin. I am using a two way 900 MHz device to extend the input and output signals from my Zwave MIMOLite to the gate controller which allows me to control from anywhere if needed and hopefully get accurate status back.

Just got back from my vacation property, and this worked great. Thanks for all the help, I now have control of my gate and status. My gate is 1000 feet from the log home, but with these devices: (https://www.controlanything.com/Relay/Device/MirXR15) along with the fortress MIMOLite I can open and close from SmartThings.
Another question is how would I add notification capabilty here? I would like to get a phone notification and text message when the gate is opened. I could not find how to implement this with the notify me smartapp as it could not find this device. Thanks Again!

I think email/text notification requires a smart app.
What app exactly are you using, it could be that the app doesn’t recognize garage door devices and you’ll need to make the device handler look like a different type of device for the notify app to work.

Thanks for the reply.
The SmartApp I am trying to use is Notify Me When, but I also tried a few others. You are correct that the SmartApp does not see the device to select it for action. I am not a code expert and don’t know what code to change to make it work, and if changed to look like a different device what effect will it have on its current operation. Not sure how hard this is to change either but if you could help or point me in the right direction I would appreciate it. I searched all over trying to find a fix for this and even experimented with it but cannot figure it out. BTW your app works great, the gate operates great and the position contact works really well so if I don’t get this working its not a big deal- but it would be sweet to get a message when the gate opens.
Thanks

I’m going to try to modify the Notfiy Me When app source code to make it work with Garage Door Openers, it is a simple app to change.

I’ll post a new version of the Notify Me Know app once I’ve tested the changes and make sure it works.

This version of the Notify Me When app will let you register garage door opening and closing events, I tested it with SMS.
Install it in “My Smart Apps” in the developer web page.

You can then select it under Marketplace / SmartApps / My Apps on your phone.

/**
 *  Copyright 2015 SmartThings
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License. You may obtain a copy of the License at:
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
 *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
 *  for the specific language governing permissions and limitations under the License.
 *
 *  Notify Me When
 *
 *  Author: SmartThings
 *  Date: 2013-03-20
 *
 * Change Log:
 *	1. Todd Wackford
 *	2014-10-03:	Added capability.button device picker and button.pushed event subscription. For Doorbell.
 *  2. Simon Capper
 *  2016-08-23: Added capability.Garage Door Control and open/close event subscription.
 */
definition(
		name: "Notify Me When",
		namespace: "smartthings",
		author: "SmartThings",
		description: "Receive notifications when anything happens in your home.",
		category: "Convenience",
		iconUrl: "https://s3.amazonaws.com/smartapp-icons/Meta/window_contact.png",
		iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Meta/window_contact@2x.png"
)

preferences {
	section("Choose one or more, when..."){
		input "button", "capability.button", title: "Button Pushed", required: false, multiple: true //tw
		input "motion", "capability.motionSensor", title: "Motion Here", required: false, multiple: true
		input "contact", "capability.contactSensor", title: "Contact Opens", required: false, multiple: true
		input "contactClosed", "capability.contactSensor", title: "Contact Closes", required: false, multiple: true
		input "acceleration", "capability.accelerationSensor", title: "Acceleration Detected", required: false, multiple: true
		input "mySwitch", "capability.switch", title: "Switch Turned On", required: false, multiple: true
		input "mySwitchOff", "capability.switch", title: "Switch Turned Off", required: false, multiple: true
		input "arrivalPresence", "capability.presenceSensor", title: "Arrival Of", required: false, multiple: true
		input "departurePresence", "capability.presenceSensor", title: "Departure Of", required: false, multiple: true
		input "smoke", "capability.smokeDetector", title: "Smoke Detected", required: false, multiple: true
		input "water", "capability.waterSensor", title: "Water Sensor Wet", required: false, multiple: true
		input "garageDoorOpen", "capability.garageDoorControl", title: "Garage Door Opened", required: false, multiple: true
		input "garageDoorClosed", "capability.garageDoorControl", title: "Garage Door Closed", required: false, multiple: true
	}
	section("Send this message (optional, sends standard status message if not specified)"){
		input "messageText", "text", title: "Message Text", required: false
	}
	section("Via a push notification and/or an SMS message"){
		input("recipients", "contact", title: "Send notifications to") {
			input "phone", "phone", title: "Phone Number (for SMS, optional)", required: false
			paragraph "If outside the US please make sure to enter the proper country code"
			input "pushAndPhone", "enum", title: "Both Push and SMS?", required: false, options: ["Yes", "No"]
		}
	}
	section("Minimum time between messages (optional, defaults to every message)") {
		input "frequency", "decimal", title: "Minutes", required: false
	}
}

def installed() {
	log.debug "Installed with settings: ${settings}"
	subscribeToEvents()
}

def updated() {
	log.debug "Updated with settings: ${settings}"
	unsubscribe()
	subscribeToEvents()
}

def subscribeToEvents() {
	subscribe(button, "button.pushed", eventHandler) //tw
	subscribe(contact, "contact.open", eventHandler)
	subscribe(contactClosed, "contact.closed", eventHandler)
	subscribe(acceleration, "acceleration.active", eventHandler)
	subscribe(motion, "motion.active", eventHandler)
	subscribe(mySwitch, "switch.on", eventHandler)
	subscribe(mySwitchOff, "switch.off", eventHandler)
	subscribe(arrivalPresence, "presence.present", eventHandler)
	subscribe(departurePresence, "presence.not present", eventHandler)
	subscribe(smoke, "smoke.detected", eventHandler)
	subscribe(smoke, "smoke.tested", eventHandler)
	subscribe(smoke, "carbonMonoxide.detected", eventHandler)
	subscribe(garageDoorOpen, "door.open", eventHandler)
	subscribe(garageDoorClosed, "door.closed", eventHandler)
}

def eventHandler(evt) {
	log.debug "Notify got evt ${evt}"
	if (frequency) {
		def lastTime = state[evt.deviceId]
		if (lastTime == null || now() - lastTime >= frequency * 60000) {
			sendMessage(evt)
		}
	}
	else {
		sendMessage(evt)
	}
}

private sendMessage(evt) {
	String msg = messageText
	Map options = [:]

	if (!messageText) {
		msg = defaultText(evt)
		options = [translatable: true, triggerEvent: evt]
	}
	log.debug "$evt.name:$evt.value, pushAndPhone:$pushAndPhone, '$msg'"

	if (location.contactBookEnabled) {
		sendNotificationToContacts(msg, recipients, options)
	} else {
		if (!phone || pushAndPhone != 'No') {
			log.debug 'sending push'
			options.method = 'push'
			//sendPush(msg)
		}
		if (phone) {
			options.phone = phone
			log.debug 'sending SMS'
			//sendSms(phone, msg)
		}
		sendNotification(msg, options)
	}

	if (frequency) {
		state[evt.deviceId] = now()
	}
}

private defaultText(evt) {
	if (evt.name == 'presence') {
		if (evt.value == 'present') {
			if (includeArticle) {
				'{{ triggerEvent.linkText }} has arrived at the {{ location.name }}'
			}
			else {
				'{{ triggerEvent.linkText }} has arrived at {{ location.name }}'
			}
		} else {
			if (includeArticle) {
				'{{ triggerEvent.linkText }} has left the {{ location.name }}'
			}
			else {
				'{{ triggerEvent.linkText }} has left {{ location.name }}'
			}
		}
	} else {
		'{{ triggerEvent.descriptionText }}'
	}
}

private getIncludeArticle() {
	def name = location.name.toLowerCase()
	def segs = name.split(" ")
	!(["work","home"].contains(name) || (segs.size() > 1 && (["the","my","a","an"].contains(segs[0]) || segs[0].endsWith("'s"))))
}

Wow! Thanks, works great.

Thanks for helping me on this, I really do appreciate it

Hi there. Pretty new to SmartThings (<1 mo) and starting to learn about Smart Apps & Custom Device Handlers.

I just installed the MimoLite with this Device Handler (working great!) and wanted to see if there was a way to get a notification if the door was still Open at a certain time (like 8pm).

With the modified “Notify Me When” SmartApp, I can get notified if the controller Opens or Closes, but does not have the capability to check the current Open/Close state and act on that.

Is there a different app that can do that? Or am I not looking in the right place to set this up.

Thanks!

Yep, you can create a custom monitoring rule in Smart Home Monitor, and under More Options select a start time and end time.

When asked what kind of device you want to use, select Open/Close, and then select the sensor(s). Next select “Sensor opens”, add any minutes to wait to notify you, then tap on “+More options”.

I do something similar, expect that it notifies me if it’s been open for 30 minutes or more between a certain time.

1 Like

Thanks.

I tried, but it’s not showing in the Open/Close Sensors list :confused:

Probably needs some tweaks to the Device Handler to have the door position available to the Smart Home Monitor?

edit: @johnconstantelo I tried your Device Handler and the door state does not change from Open, even when the MimoLite triggers the relay and the door is closed. Not sure what the issue is (I’m using a mag switch, not a potenionmeter)

Yes it wont work with the version of code you have, the smart home monitor only work with a Contact Sensor, The updated device handler below adds this capability to my original handler, install it and you’ll be able to add the custom rule. I’ve done some basic testing. It will report open when the door is open, opening or closing and report closed only when the door is fully closed. Let me know if you have any issues.

/**
 *  MIMOlite as a Garage Door Control with Potentiometer Multi Sensor
 *
 *  Copyright 2016 Simon Capper
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License. You may obtain a copy of the License at:
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
 *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
 *  for the specific language governing permissions and limitations under the License.
 *
 * Inspired by a similar handler written by https://community.smartthings.com/users/johnconstantelo
 */
metadata {
definition (name: "MIMOlite - Garage Door Control", namespace: "skyjunky", author: "Simon Capper") {
    capability "Polling"
    capability "Refresh"
    capability "Momentary"
    capability "Configuration"
    capability "Garage Door Control"
		capability "Contact Sensor"
		attribute "powerSupply", "string"
    attribute "doorPosition", "number"
    attribute "doorPositionClosed", "number"
    attribute "doorPositionOpen", "number"
    command "setOpenPosition"
    command "setClosedPosition"
    fingerprint deviceId:"0x1000", inClusters:"0x72, 0x86, 0x71, 0x30, 0x31, 0x35, 0x70, 0x85, 0x25"
}

// UI tile definitions
tiles(scale:2) {
    multiAttributeTile(name:"door", type: "generic", width: 6, height: 4){
        tileAttribute ("device.door", key: "PRIMARY_CONTROL") {
            attributeState "open", label: "Open", action: "push", icon: "st.doors.garage.garage-open", backgroundColor: "#ffa81e", nextState:"closing"
            attributeState "opening", label: "Opening", action: "push", icon: "st.doors.garage.garage-opening", backgroundColor: "#ffffff", nextState:"closing"
            attributeState "closed", label: "Closed", action: "push", icon: "st.doors.garage.garage-closed", backgroundColor: "#79b821", nextState:"opening"
            attributeState "closing", label: "Closing", action: "push", icon: "st.doors.garage.garage-closing", backgroundColor: "#ffffff", nextState:"opening"
            attributeState "unknown", label: "Power Out", icon: "st.alarm.alarm.alarm", backgroundColor: "#bc2323"
        }
        tileAttribute ("powerSupply", key: "SECONDARY_CONTROL") {
            attributeState "good", label: "Power Good"
            attributeState "powerOutOpen", label: "Power Out - Door Open"
            attributeState "powerOutClosed", label: "Power Out - Door Closed"
        }
    }
    valueTile ("doorPositionOpen", "device.doorPositionOpen", width: 5, height: 1) {
        state "doorPositionOpen", label: 'Configured Open Position ${currentValue}'
    }
    standardTile ("setOpenPos", "setOpenPos", decoration: "flat" ) {
        state "setOpenPos", label: '', action: 'setOpenPosition', icon: "st.secondary.configure"
    }
    valueTile ("doorPositionClosed", "device.doorPositionClosed", width: 5, height: 1) {
        state "doorPositionClosed", label: 'Configured Close Position ${currentValue}'
    }
    standardTile ("setClosedPos", "setClosedPos", decoration: "flat") {
        state "setClosedPos", label: '', action: 'setClosedPosition', icon: "st.secondary.configure"
    }
    valueTile ("doorPosition", "device.doorPosition", width: 5, height: 1) {
        state "doorPosition", label: 'Current Door Position ${currentValue}'
    }

    main "door"
    details(["door", "doorPositionOpen", "setOpenPos", 
             "doorPositionClosed", "setClosedPos", "doorPosition"])
}
}

def parse(String description) {
def result = null
// supported classes
// 0x20 - BasicSet used to report when the sensor trigger level changes
// 0x25 - switch binary V1
// 0x30 - sensor binary V1
// 0x31 - sensor multilevel V1
// 0x35 - meter pulse (not tested)
// 0x70 - configuration V1
// 0x71 - alarm V1 (for supply voltage monitor, does not seem to respond to AlarmGet)
// 0x72 - manufacturer specific V1
// 0x85 - association V1
// 0x86 - version V1

def cmd = zwave.parse(description, [0x20: 1, 0x25: 1, 0x86: 1, 0x30: 1, 0x31: 1, 0x72: 1, 0x71: 1])
if (cmd) {
    result = createEvent(zwaveEvent(cmd))
    if (result) {
        log.debug "Parsed command: ${result?.descriptionText} raw: ${description}"
    } else {
        log.debug "Unhandled command: ${description}"
    }
} else {
    log.debug "Unparsed command: ${description}"
}
return result
}

def getSensitivity() {
return 0x1
}

def getPotOpen() {
def rc = device.currentValue("doorPositionOpen")
if (rc == null) {
    sendEvent(name: "doorPositionOpen", value: 158)
    return 158
}
return rc
}

def getPotClosed() {
def rc = device.currentValue("doorPositionClosed")
if (rc == null) {
    sendEvent(name: "doorPositionClosed", value: 0)
    return 0
}
return rc    
}

def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) {
// trigger fires, request the door position so we can see what state it is in
poll().collect { sendHubCommand(new physicalgraph.device.HubAction(it)) }
return null
}

def zwaveEvent(physicalgraph.zwave.commands.alarmv1.AlarmReport cmd) {
if (cmd.alarmLevel) {
    if (device.currentValue("door") == "closed") {
        sendEvent(name: "powerSupply", value: "powerOutClosed")
    } else {
        sendEvent(name: "powerSupply", value: "powerOutOpen")
    }
    return [name: "door", value: "unknown"]
}
return null
}

def convertSensorValueToDoorState( BigDecimal sensorValue ) {
def upper = (potOpen < potClosed) ? potClosed : potOpen
def lower = (potOpen > potClosed) ? potClosed : potOpen
def upperState = (potOpen > potClosed) ? "open" : "closed"
def lowerState = (potOpen < potClosed) ? "open" : "closed"

if (sensorValue >= (upper - sensitivity)) {
    return upperState
} else if (sensorValue <= (lower + sensitivity)) {
    return lowerState
} else if (device.currentValue('door') == "open") {
    return 'closing'
} else if (device.currentValue('door') == "closed") {
    return 'opening'
}
return device.currentValue('door')
}

def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv1.SensorMultilevelReport cmd) {
// if we are in a power fail state this is the first message we'll get after the power comes back
// so update the powerState
if (device.currentValue('powerSupply') != "good") {     
    sendEvent(name: "powerSupply", value: "good")
}

def adjustedValue = cmd.scaledSensorValue.intValue() >> 4
if (adjustedValue != device.currentValue('doorPosition')) {
    def doorState = convertSensorValueToDoorState( adjustedValue )
    sendEvent(name: "doorPosition", value: adjustedValue)
    if (doorState == "closed") {
    	sendEvent(name: "contact", value: "closed")
    } else {
    	sendEvent(name: "contact", value: "open")
		}
    if (device.currentValue('door') != doorState) {     
        return [name: "door", value: doorState]
    }
}
return null
}

def zwaveEvent(physicalgraph.zwave.Command cmd) {
// Handles all Z-Wave commands we aren't interested in
return null
}

def open() {
if (device.currentValue("door") == "closed") {
    push()
}
}

def close() {
if (device.currentValue("door") == "open") {
    push()
}
}

def push() {
def cmds = delayBetween([
    zwave.switchBinaryV1.switchBinarySet(switchValue: 0xff).format(),
],500)
return cmds
}

def poll() {
delayBetween([
    zwave.sensorMultilevelV1.sensorMultilevelGet().format(),
],500)
}

def refresh() {
delayBetween([
    zwave.sensorMultilevelV1.sensorMultilevelGet().format(),
],500)
}

def updated() {
// called when the device is updated
configure()
}

def installed() {
// called when the device is installed
configure()
}

def configure() {
log.debug "configure"
def cmds = delayBetween([
   // enable analog alert thresholds
    zwave.configurationV1.configurationSet(scaledConfigurationValue: 0, parameterNumber: 8, size: 2).format(),
    // turn on momentary button press, this presses it for 1 second
    zwave.configurationV1.configurationSet(scaledConfigurationValue: 10, parameterNumber: 11, size: 2).format(),
    // tell device to send multivalue sensor updates every 10 seconds 
    zwave.configurationV1.configurationSet(scaledConfigurationValue: 1, parameterNumber: 9, size: 2).format(),
    // enable alarms to be sent to smartthings hub
    zwave.associationV1.associationSet(groupingIdentifier:3, nodeId:[zwaveHubNodeId]).format(),
    // enable multivalue sensor updates to be sent to smartthings hub
    zwave.associationV1.associationSet(groupingIdentifier:2, nodeId:[zwaveHubNodeId]).format(),
 ],500)
 return cmds
}
1 Like

Thanks, skyjunky!

I’ll give it a whirl tonight![quote=“skyjunky, post:35, topic:46696, full:true”]
Yes it wont work with the version of code you have, the smart home monitor only work with a Contact Sensor, The updated device handler below adds this capability to my original handler, install it and you’ll be able to add the custom rule. I’ve done some basic testing. It will report open when the door is open, opening or closing and report closed only when the door is fully closed. Let me know if you have any issues.

[/quote]

I had a break @ work so updated the device handler and it looks like it’s working so far! :+1:

It took several minutes for the Contact state to change to closed so I thought it was not working, at first, since the door position was at 0 / closed.

Yes, that is to be expected, you need to either wait or quickly open/close the door to update the new contact state.

1 Like

I assume its OK for me to link my question from another thread, if not-- apologies. Any help would be appreciated.

You wont be able to use the device handler I wrote in this thread to monitor the EcoLink tilt sensor.
To make this work you’ll need to create a virtual device handler that makes the mmiolite and ecolink devices look like a single device.
If you are not comfortable writing the software to do this and can’t find one that someone else has written it will be easier to hook up a regular wired contact switch and hook it up to the mmio input, the device handler in this thread will work fine with that. Cost should be less than $10, you’ll just have to deal with the hassle of wiring it up.