The Ultimate Smart Home Integration Cookbook
Integration: It enables the smart home hub to communicate and work with various smart devices or services.
The Alexa Speaks: Shared Devices integration works very similarly to the Alexa Speaks integration, but instead of creating a 3rd party connection between the two systems, it uses the officially supported Alexa Skill. With Alexa, you will create and share a virtual device on your smart home hub. Then you will then use that device as a trigger inside routines and have Alexa speak the notification. There are a few cavoites to this method. The easiest way would be to create a Virtual Switch. However, Alexa cannot use switches to trigger routines from some smart home hub skills but can use contact sensors. You need to be aware of these limitations and develop a solution that works best.
Automation Details
Required Devices
- Virtual Device
- Voice Assistant
Triggers:
- Virtual Hybrid Contact Switch turns On
Actions:
- Alexa Speaks Notification
Hubitat
Important: This integration requires Amazon Echo Skill outlined in Hubitat Connect.
Setting Up the Automation
First, go to the Drivers code and click New Driver.
Alexa can not use a switch to trigger a routine and Hubitat doesn’t allow you to change a virtual contact sensor from rules machine. We will need to create a hybrid driver that Alexa sees as a Contact Sensor and Hubitat sees as a switch.
Copy and paste the below code in to the new Driver window. Then click Save and then Drivers code to exit the editor.
/** * Virtual Hybrid Contact Switch * * MIT License * * Copyright (c) 2023 This Old Smart Home * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ public static String version() { return "v2.0.3" } public static String name() { return "Virtual Hybrid Contact Switch" } public static String codeUrl() { return "https://raw.githubusercontent.com/TOSH-SmartHome/Hubitat-Virtual-Hybrid-Contact-Switch/main/virtual_hybrid_contact_switch.groovy" } public static String driverInfo() { return """ <p style='text-align:center'></br> <strong><a href='https://thisoldsmarthome.com' target='_blank'>This Old Smart Home</a></strong> (TOSH-SmartHome)</br> ${name()}</br> <em>${version()}</em></p> """ } metadata { definition (name: name(), namespace: "tosh", author: "John Goughenour", importUrl: codeUrl()) { capability "Sensor" capability "Contact Sensor" capability "Switch" command "sendMqttOn" command "sendMqttOff" } preferences { input(name: "mqttBroker", type: "string", title: "<b>MQTT Broker</b>", description: "Enter MQTT Broker IP and Port e.g. server_IP:1883", required: false) input(name: "mqttUsername", type: "string", title: "<b>MQTT Username</b>", description: "Enter MQTT broker username", required: false) input(name: "mqttPassword", type: "password", title: "<b>MQTT Password</b>", description: "Enter password for your MQTT Broker", required: false) input name: "autoOff", type: "number", title: "<b>Auto Off</b>", description: "Automatically turn off device after x many seconds </br>Default: 0 (Disabled)", defaultValue: 0, required: false input(name: "infoLogging", type: "bool", title: "<b>Enable Description Text</b>", defaultValue: "true", description: "", required: false) input(name: "debugLogging", type: "bool", title: "<b>Enable Debug Logging</b>", defaultValue: "false", description: "", required: false) input name:"about", type: "text", title: "<b>About Driver</b>", description: "A hybrid contact sensor/swtich that can be used in Hubitat to trigger Alexa Routines. ${driverInfo()}" } } def installed() { if(infoLogging) log.info "${device.displayName} is installing" initialize() } def updated() { if(infoLogging) log.info "${device.displayName} is updating" initialize() } def uninstalled() { if(infoLogging) log.info "${device.displayName} is uninstalling" } def initialize() { if(infoLogging) log.info "${device.displayName} is initializing" if(mqttBroker && mqttUsername) state.mqtt = true else state.mqtt = false sendEvent(name: "switch", value: "off") sendEvent(name: "contact", value: "closed") } // handle commands def on() { if(infoLogging) log.info "${device.displayName} is turned on" sendEvent(name: "switch", value: "on") sendEvent(name: "contact", value: "open") if(state.mqtt) sendMqttCommand("on") if( autoOff > 0 ) runIn (autoOff, off) } def off() { if(infoLogging) log.info "${device.displayName} is turned off" sendEvent(name: "switch", value: "off") sendEvent(name: "contact", value: "closed") if(state.mqtt) sendMqttCommand("off") } def sendMqttOn() { if(infoLogging) log.info "${device.displayName} sendMqttOn was triggered" if(state.mqtt) sendMqttCommand("on") } def sendMqttOff() { if(infoLogging) log.info "${device.displayName} sendMqttOff was triggered" if(state.mqtt) sendMqttCommand("off") } def sendMqttCommand(cmnd) { if(debugLogging) log.debug "${device.displayName} MQTT sending Command: ${cmnd}" try { if(debugLogging) log.debug "${device.displayName} settting up MQTT Broker" interfaces.mqtt.connect( "tcp://${mqttBroker}", "${location.hub.name.toLowerCase().replaceAll(' ', '_')}_${device.getDeviceNetworkId()}", mqttUsername, mqttPassword ) if(debugLogging) log.debug "${device.displayName} is sending Topic: cmnd/${device.displayName.toLowerCase().replaceAll(' ', '_')} Command: ${cmnd}" interfaces.mqtt.publish( "cmnd/${device.displayName.toLowerCase().replaceAll(' ', '_')}", "${cmnd}", 2, false ) } catch(Exception e) { log.error "${device.displayName} unable to connect to the MQTT Broker ${e}" } interfaces.mqtt.disconnect() } // parse events and messages def mqttClientStatus(message) { switch(message) { case ~/.*Connection succeeded.*/: if(debugLogging) log.debug "MQTT Client Status: ${device.displayName} successfully connected to MQTT Broker" break case ~/.*Error.*/: log.error "MQTT Client Status: ${device.displayName} unable to connect to MQTT Broker - ${message}" break default: log.warn "MQTT Client Status: ${device.displayName}: unknown status - ${message}" } }
Next, go to Devices and then click Add Device.
Click the Virtual button.
Fill out the Device Information as follows:
- Enter the Device Name, I like to use the type of virtual device it is.
- Enter the Device Label, this is what will be shown in Alexa.
- Set the Type to Virtual Hybrid Contact Switch (user).
- Optional, add the device to a room.
- Then click the Save Device button.
In the device preferences, Enable auto-off and set it to 1 second. Then click the Save Preferences button. Then share the device with Alexa as outlined in Hubitat Connect
Success: That’s It! Then, you would create an automation in Hubitat to turn the switch on. Next, go to the Alexa app to set up the routine.