Somfy ZWave Blinds (Dimmer)

@tonesto7 is maintaining this code for both Hubitat and ST.

You may want to go to his github and file an Issue:

He doesn't get notification of messages from this community - he checks in and finds he has a dozen, for example.

I think this is a HE issue. Like I said the same issue arises when I use both Siri and Alexa.

Prior to 2.0 Open and Close both worked using Siri and Alexa.__

Why wouldn’t you port the app to change with how HE works? Just curious if adding a couple lines in a posted ST app would be better than to clutter the switch category? My home has 35 windows with blinds in it. That would be 35 switches I would have to deal with in non-blind applications to scroll or accidentally select.

Just saying my preference is we don’t replicate bad programming practices because of a platform that didn’t listen to its community and then the community got creative with switches.

1 Like

I actually suggested this approach from the beginning. HE should expose the actual device driver code so the community can make it their own and get it perfectly correct.

1 Like

Current thinking, I agree.

Anyone have a thought on this one..... my curtains are currently closed (for real) and home bridge shows them as open.

When I try to close them using home bridge/siri or alexa this is the resulting log.

[dev:12](http://192.168.7.201/logs#dev12)2018-12-08 10:13:13.907 pm [error](http://192.168.7.201/device/edit/12)groovy.lang.GroovyRuntimeException: Ambiguous method overloading for method java.lang.Integer#minus. Cannot resolve which method to invoke for [null] due to overlapping prototypes between: [class java.lang.Character] [class java.lang.Number] (setPosition)

Anyone? This is quite annoying.

Hi, I'm a total noob in the home automation space. Just got my hubitat and trying to get my first device, a Bali shade which uses the Somfy z-wave motor to work. I was able to get the shade paired and it used the Generic Z-Wave Shade driver. It properly detects the Current states fine, but none of the controls work at all. ON/OFF and Open/Close do nothing. Does the driver maybe need an update for this specific motor? I also got the 2 button remote added to hubitat as well as connected to the shade. It will open the shade if I physically press the button, but if I use hubitat to virtually push the button, it detects the push, but the shade does not open/close. help!

Here are the shade device details and logs:

  • deviceType: 21075
  • inClusters: 0x5E,0x26,0x85,0x59,0x72,0x86,0x5A,0x73,0x25,0x7A,0x80
  • deviceId: 23089
  • manufacturer: 622

dev:52019-01-06 05:09:19.663 pm infoSouth Shade is closed
dev:52019-01-06 05:09:19.650 pm infoSouth Shade battery level is 100%
dev:52019-01-06 05:09:17.255 pm errorjava.lang.NumberFormatException: For input string: "" (open)
dev:52019-01-06 05:09:17.227 pm infoSouth Shade is opening
dev:52019-01-06 05:09:16.015 pm errorjava.lang.NumberFormatException: For input string: "" (on)
dev:52019-01-06 05:09:15.989 pm infoSouth Shade is opening
dev:52019-01-06 05:09:14.504 pm errorjava.lang.NumberFormatException: For input string: "" (off)
dev:52019-01-06 05:09:14.475 pm infoSouth Shade is closing
dev:52019-01-06 05:09:12.946 pm errorjava.lang.NumberFormatException: For input string: "" (close)
dev:52019-01-06 05:09:12.839 pm infoSouth Shade is closing

The built in Hubitat driver didn't work for me either. I can tell by your manufacturer and deviceID, we have the same motors. This is what I am using. I don't remember where I got it because I have been using it for a long time, but most likely got this from the ST community and did a simple find and replace conversion to get it to work. Tagging @mike.maxwell because he is the Hubitat Driver master.

/**
 *  Copyright 2016 ericvitale@gmail.com
 *
 *  Version 1.0.6 - Cleaned up a bit. 06/30/2017
 *  Version 1.0.5 - Added auto-detect support for Somfy by Bali. 03/31/2017
 *  Version 1.0.4 - Added support for the Window Shade capability. 10/15/2016
 *  Version 1.0.3 - Tweaked configuration calling.
 *  Version 1.0.2 - Added support for poll, fixed battery reporting bug.
 *  Version 1.0.1 - Added support for battery level.
 *  Version 1.0.0 - Initial Release
 *
 *  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.
 *
 *  You can find this device handler @ https://github.com/ericvitale/ST-Z-Wave-Shade
 *  You can find my other device handlers & SmartApps @ https://github.com/ericvitale
 *
 *  Credit to SmartThings for the following device handler
 *  https://github.com/SmartThingsCommunity/SmartThingsPublic/blob/master/devicetypes/smartthings/zwave-dimmer-switch-generic.src/zwave-dimmer-switch-generic.groovy
 *
 */
 
def dhVersion() { return "1.0.2" } 
 
metadata {
	definition (name: "Z-Wave Shade", namespace: "ericvitale", author: "ericvitale@gmail.com") {
		capability "Switch Level"
		capability "Actuator"
		capability "Switch"
		capability "Polling"
		capability "Refresh"
		capability "Sensor"
    capability "Battery"
    capability "Configuration"
    capability "Window Shade"
    
    command "sceneOne"
    command "sceneTwo"
    command "sceneThree"
    command "sceneFour"
    command "sceneFive"
    command "getBattery"
    command "doPoll"
    command "levelOpenClose"
    
    attribute "lastActivity", "string"
    attribute "lastConfigured", "string"
    attribute "lastPoll", "string"
    attribute "lastBattery", "string"
    
    fingerprint mfr: "026E", prod: "4345", model: "0038"
    fingerprint mfr: "026E", prod: "4345", model: "5A31"
    fingerprint deviceId: "0x1007", inClusters: "0x5E,0x80,0x25,0x70,0x72,0x59,0x85,0x73,0x7A,0x5A,0x86,0x20,0x26", outClusters: "0x82", deviceJoinName: "Z-Wave Shade"
    fingerprint deviceId: "0x1107", inClusters: "0x5E,0x80,0x25,0x70,0x72,0x59,0x85,0x73,0x7A,0x5A,0x86,0x20,0x26", outClusters: "0x82", deviceJoinName: "Z-Wave Shade" 
	}

preferences {
	    input "customLevel", "number", title: "Custom Level", required: true, defaultValue: 66, range: "0..100"
    input "logging", "enum", title: "Log Level", required: false, defaultValue: "INFO", options: ["TRACE", "DEBUG", "INFO", "WARN", "ERROR"]
}

	tiles(scale: 2) {
	multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
			tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
				attributeState "on", label:'${name}', action:"switch.off", icon:"st.Home.home9", backgroundColor:"#79b821", nextState:"turningOff"
				attributeState "off", label:'${name}', action:"switch.on", icon:"st.Home.home9", backgroundColor:"#ffffff", nextState:"turningOn"
				attributeState "turningOn", label:'${name}', action:"switch.on", icon:"st.Home.home9", backgroundColor:"#79b821", nextState:"turningOff"
				attributeState "turningOff", label:'${name}', action:"switch.off", icon:"st.Home.home9", backgroundColor:"#ffffff", nextState:"turningOn"
			}
			
        tileAttribute ("device.level", key: "SLIDER_CONTROL") {
				attributeState "level", action:"switch level.setLevel"
			}
		}
		multiAttributeTile(name:"switchDetails", type: "lighting", width: 6, height: 4, canChangeIcon: true){
			tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
				attributeState "on", label:'${name}', action:"switch.off", icon:"st.Home.home9", backgroundColor:"#79b821", nextState:"turningOff"
				attributeState "off", label:'${name}', action:"switch.on", icon:"st.Home.home9", backgroundColor:"#ffffff", nextState:"turningOn"
				attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.Home.home9", backgroundColor:"#79b821", nextState:"turningOff"
				attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.Home.home9", backgroundColor:"#ffffff", nextState:"turningOn"
			}
        
        tileAttribute ("device.battery", key: "SECONDARY_CONTROL") {
				attributeState "default", label:'Battery: ${currentValue}%', action: "refresh.refresh"
			}
		}

		standardTile("refresh", "device.switch", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
			state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
		}
    
    valueTile("ShadeLevel", "device.level", width: 2, height: 1) {
    	state "level", label: 'Shade is ${currentValue}% up'
    }
    
    controlTile("levelSliderControl", "device.level", "slider", width: 4, height: 1) {
    	state "level", action:"switch level.setLevel"
    }
    
    standardTile("sceneOne", "device.sceneOne", inactiveLabel: false, decoration: "flat", height: 2, width: 2) {
			state "default", label:'${currentValue}%', action:"sceneOne", icon: "st.Weather.weather14"
		}
    
    standardTile("sceneTwo", "device.sceneTwo", inactiveLabel: false, decoration: "flat", height: 2, width: 2) {
			state "default", label:"20%", action:"sceneTwo", icon: "st.Weather.weather14"
		}
    
    standardTile("sceneThree", "device.sceneThree", inactiveLabel: false, decoration: "flat", height: 2, width: 2) {
			state "default", label:"40%", action:"sceneThree", icon: "st.Weather.weather14"
		}
    
    standardTile("sceneFour", "device.sceneFour", inactiveLabel: false, decoration: "flat", height: 2, width: 2) {
			state "default", label:"60%", action:"sceneFour", icon: "st.Weather.weather14"
		}
    
    standardTile("sceneFive", "device.sceneFive", inactiveLabel: false, decoration: "flat", height: 2, width: 2) {
			state "default", label:"80%", action:"sceneFive", icon: "st.Weather.weather14"
		}

		valueTile("level", "device.level", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
			state "level", label:'${currentValue} %', unit:"%", backgroundColor:"#ffffff"
		}
    
    standardTile("doPoll", "device.doPoll", inactiveLabel: false, decoration: "flat", height: 2, width: 2) {
			state "default", label:"Do Poll", action:"doPoll", icon: "st.Weather.weather14"
		}
    
    valueTile("LastActivity", "device.lastActivity", width: 6, height: 2) {
    	state "default", label: 'Last Activity ${currentValue}'
    }
    
    valueTile("LastConfigured", "device.lastConfigured", width: 6, height: 2) {
    	state "default", label: 'Last Configured ${currentValue}'
    }
    
    valueTile("LastPoll", "device.lastPoll", width: 6, height: 2) {
    	state "default", label: 'Last Poll ${currentValue}'
    }
    
    valueTile("LastBattery", "device.lastBattery", width: 6, height: 2) {
    	state "default", label: 'Last Battery ${currentValue}'
    }

    main(["switch", "level"])
	details(["switchDetails", "ShadeLevel", "levelSliderControl", "sceneOne", "sceneTwo", "sceneThree", "sceneFour", "sceneFive", "refresh", "top", "bottom"])

	}
}

def installed() {
	poll()
}

def configure() {
delayBetween([
		def result = zwave.wakeUpV1.wakeUpNoMoreInformation().format(),
    zwave.wakeUpV1.wakeUpIntervalSet(seconds:4 * 3600, nodeid:zwaveHubNodeId).format()
	])
}

def updated() {
log("${getVersionStatementString()}", "DEBUG")

	sendEvent(name: "sceneOne", value: customLevel, display: false , displayed: false)
log("Custom Level Selected: ${customLevel}.", "INFO")
log("Debug Level Selected: ${logging}.", "INFO")

poll()
}

def doPoll() {
	poll()
}

def poll() {
	log("Polling...", "DEBUG")

updateDeviceLastPoll(new Date())

log("${getVersionStatementString()}", "DEBUG")

configCheck()

def commands = []
	
commands << zwave.switchMultilevelV1.switchMultilevelGet().format()
commands << zwave.batteryV1.batteryGet().format()
	
if (getDataValue("MSR") == null) {
		commands << zwave.manufacturerSpecificV1.manufacturerSpecificGet().format()
	}
	
def result = delayBetween(commands,100)

log("result = ${result}", "DEBUG")

return result
}

def refresh() {
	
log("Refreshing.", "DEBUG")
log("${getVersionStatementString()}", "DEBUG")
log("windowShade = ${device.currentValue('windowShade')}.", "INFO")
	
def commands = []
	commands << zwave.switchMultilevelV1.switchMultilevelGet().format()
commands << zwave.batteryV1.batteryGet().format()
	if (getDataValue("MSR") == null) {
		commands << zwave.manufacturerSpecificV1.manufacturerSpecificGet().format()
	}
	def result = delayBetween(commands,100)
log("result = ${result}", "DEBUG")

return result
}

def parse(String description) {
	def result = null
	if (description != "updated") {
		log("parse() >> zwave.parse($description)", "DEBUG")
    if(description.trim().endsWith("payload: 00 00 00")) {
    	sendEvent(name: "level", value: 0, unit: "%")
        log("Shade is down, setting level to 0%.", "DEBUG")
    } else if(description.contains("command: 2603")) {
    	def hexVal = description.trim()[-8..-7]
        def movingHex = description.trim()[-2..-1]
        log("hexVal = ${hexVal}.", "DEBUG")
        try {
            def intVal = zigbee.convertHexToInt(hexVal)
            def movingInt = zigbee.convertHexToInt(movingHex)
            log("intVal = ${intVal}.", "DEBUG")
            
            if(movingInt == 0) {
            	log("Shade has stopped.", "INFO")
            } else if(movingInt == 254) {
            	log("Shade is moving.", "INFO")
            } else {
            	log("movingInt = ${movingInt}.", "INFO")
            }
            
            sendEvent(name: "level", value: intVal, unit: "%")
        } catch(e) {
        	log("Exception ${e}", "ERROR")
        }
    } else if(description.contains("command: 8003")) {
    	log("Battery Reported.", "DEBUG")
    }
    
		def cmd = zwave.parse(description, [0x20: 1, 0x26: 1, 0x70: 1])
		if (cmd) {
			result = zwaveEvent(cmd)
		}
	}
	if (result?.name == 'hail' && hubFirmwareLessThan("000.011.00602")) {
		result = [result, response(zwave.basicV1.basicGet())]
		log("Was hailed: requesting state update", "DEBUG")
	} else {
		log("Parse returned ${result?.descriptionText}", "DEBUG")
	}

	return result
}

def configCheck() {
if(shouldReconfigure() == true || isConfigured() == false) {
	log("Reconfiguring the device as the state value has changed.", "DEBUG")
    configure()
    setStateVersion(getNewStateVersion())
    state.configured = true
    updateDeviceLastConfigured(new Date())
} else {
	log("Device already configured.", "DEBUG")
}
}

def zwaveEvent(hubitat.zwave.commands.batteryv1.BatteryReport cmd) {
    log("BatteryReport", "INFO")
    def map = [ name: "battery", unit: "%" ]
    if (cmd.batteryLevel == 0xFF) {  // Special value for low battery alert
            map.value = 1
            map.descriptionText = "${device.displayName} has a low battery"
            map.isStateChange = true
    } else {
            map.value = cmd.batteryLevel
    }
    // Store time of last battery update so we don't ask every wakeup, see WakeUpNotification handler
    state.lastbatt = new Date().time
    updateDeviceLastBattery(new Date())
    createEvent(map)
}

def zwaveEvent(hubitat.zwave.commands.wakeupv2.WakeUpNotification cmd) {
	log("WakeUpNotification", "INFO")
updateDeviceLastActivity(new Date())
    def result = [createEvent(descriptionText: "${device.displayName} woke up", isStateChange: false)]

    if (!state.lastbatt || (new Date().time) - state.lastbatt > 24*60*60*1000) {
            result << response(zwave.batteryV1.batteryGet())
            result << response("delay 1200")  // leave time for device to respond to batteryGet
    }
    result << response(zwave.wakeUpV1.wakeUpNoMoreInformation())
    result
}

def zwaveEvent(hubitat.zwave.commands.basicv1.BasicReport cmd) {
	dimmerEvents(cmd)
}

def zwaveEvent(hubitat.zwave.commands.basicv1.BasicSet cmd) {
	dimmerEvents(cmd)
}

def zwaveEvent(hubitat.zwave.commands.switchmultilevelv1.SwitchMultilevelReport cmd) {
	dimmerEvents(cmd)
}

def zwaveEvent(hubitat.zwave.commands.switchmultilevelv1.SwitchMultilevelSet cmd) {
	dimmerEvents(cmd)
}

private dimmerEvents(hubitat.zwave.Command cmd) {
	def value = (cmd.value ? "on" : "off")
	def result = [createEvent(name: "switch", value: value)]
	if (cmd.value && cmd.value <= 100) {
		result << createEvent(name: "level", value: cmd.value, unit: "%")
	}
	return result
}

def zwaveEvent(hubitat.zwave.commands.configurationv1.ConfigurationReport cmd) {
	log.debug "ConfigurationReport $cmd"
	def value = "when off"
	if (cmd.configurationValue[0] == 1) {value = "when on"}
	if (cmd.configurationValue[0] == 2) {value = "never"}
	createEvent([name: "indicatorStatus", value: value])
}

def zwaveEvent(hubitat.zwave.commands.hailv1.Hail cmd) {
	createEvent([name: "hail", value: "hail", descriptionText: "Switch button was pressed", displayed: false])
}

def zwaveEvent(hubitat.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
	log.debug "manufacturerId:   ${cmd.manufacturerId}"
	log.debug "manufacturerName: ${cmd.manufacturerName}"
	log.debug "productId:        ${cmd.productId}"
	log.debug "productTypeId:    ${cmd.productTypeId}"
	def msr = String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId)
	updateDataValue("MSR", msr)
	updateDataValue("manufacturer", cmd.manufacturerName)
	createEvent([descriptionText: "$device.displayName MSR: $msr", isStateChange: false])
}

def zwaveEvent(hubitat.zwave.commands.switchmultilevelv1.SwitchMultilevelStopLevelChange cmd) {
	[createEvent(name:"switch", value:"on"), response(zwave.switchMultilevelV1.switchMultilevelGet().format())]
}

def zwaveEvent(hubitat.zwave.Command cmd) {
	// Handles all Z-Wave commands we aren't interested in
log("Unhandled Event ${cmd}", "DEBUG")
	[:]
}

def on() {
setLevel(99)
}

def off() {
	setLevel(0)
}

def setLevel(level) {
	log("setLevel(${level}).", "DEBUG")

if(level >= 100) {
	level = getMaxLevel()
} else if(level < 0) {
	level = 0
}

	if (level > 0 && level < 99) {
		sendEvent(name: "switch", value: "on")
    sendEvent(name: "windowShade", value: "partially open")
	} else if(level == 0) {
		sendEvent(name: "switch", value: "off")
    sendEvent(name: "windowShade", value: "closed")
	} else {
	sendEvent(name: "windowShade", value: "open")
}

	sendEvent(name: "level", value: level, unit: "%")
	delayBetween ([zwave.basicV1.basicSet(value: level).format(), zwave.switchMultilevelV1.switchMultilevelGet().format()], 5000)
}

def setLevel(value, duration) {
	setLevel(value)
}

def open() {
	setLevel(getMaxLevel())
}

def close() {
	setLevel(0)
}

def presetPosition() {
	setLevel(customLevel)
}

def levelOpenClose(value) {
log("levelOpenClose called with value ${value}.", "DEBUG")
if (value) {
    on()
} else {
    off()
}
}

/************ Begin Logging Methods *******************************************************/

def determineLogLevel(data) {
switch (data?.toUpperCase()) {
    case "TRACE":
        return 0
        break
    case "DEBUG":
        return 1
        break
    case "INFO":
        return 2
        break
    case "WARN":
        return 3
        break
    case "ERROR":
    	return 4
        break
    default:
        return 1
}
}

def log(data, type) {
data = "Z-Wave Shade -- v${dhVersion()} --  ${data ?: ''}"
    
if (determineLogLevel(type) >= determineLogLevel(settings?.logging ?: "INFO")) {
    switch (type?.toUpperCase()) {
        case "TRACE":
            log.trace "${data}"
            break
        case "DEBUG":
            log.debug "${data}"
            break
        case "INFO":
            log.info "${data}"
            break
        case "WARN":
            log.warn "${data}"
            break
        case "ERROR":
            log.error "${data}"
            break
        default:
            log.error "Z-Wave Shade -- Invalid Log Setting"
    }
}
}

/************ End Logging Methods *********************************************************/

def sceneOne() {
setLevel(customLevel)
}

def sceneTwo() {
setLevel(20)
}

def sceneThree() {
setLevel(40)
}

def sceneFour() {
setLevel(60)
}

def sceneFive() {
setLevel(80)
}

def getMaxLevel() {
	return 99
}

def isConfigured() {
	log("${getVersionStatementString()}", "DEBUG")
	if (state.configured == null || state.configured == false) {
	return false
	} else {
	return true
}
}

def getStateVersion() {
	if(state.version != null) {
		return state.version
} else {
	return 0
}
}

def setStateVersion(val) {
	log("Updating State Version to ${val}.", "INFO")
	state.version = val
}

def getNewStateVersion() {
	return 10
}

def getVersionStatementString() {
	return "Current state version is ${getStateVersion()} and new state version is ${getNewStateVersion()}."
}

def shouldReconfigure() {
	if(getNewStateVersion() > getStateVersion()) {
	return true
} else {
	return false
}
}

def getBattery() {
	def commands = []
commands << zwave.batteryV1.batteryGet().format()
	def result = delayBetween(commands,100)
log("result = ${result}", "DEBUG")
return result
}

def updateDeviceLastActivity(lastActivity) {
	def finalString = lastActivity?.format('MM/d/yyyy hh:mm a',location.timeZone)
	sendEvent(name: "lastActivity", value: finalString, display: false , displayed: false)
}

def updateDeviceLastConfigured(lastConfigured) {
	def finalString = lastConfigured?.format('MM/d/yyyy hh:mm a',location.timeZone)
log("Raising lastConfigured event with ${finalString}.", "INFO")
	sendEvent(name: "lastConfigured", value: finalString, display: false , displayed: false)
}

def updateDeviceLastPoll(lastPoll) {
	def finalString = lastPoll?.format('MM/d/yyyy hh:mm a',location.timeZone)    
	sendEvent(name: "lastPoll", value: finalString, display: false , displayed: false)
}

def updateDeviceLastBattery(lastBattery) {
	def finalString = lastBattery?.format('MM/d/yyyy hh:mm a',location.timeZone)    
	sendEvent(name: "lastBattery", value: finalString, display: false , displayed: false)
}
2 Likes

So to hopefully be able to finally say “Hey Siri Close the Curtains” or “Alexa Close the Curtains” without extreme work around, please examine this thread.

I think the default HE driver needs to be tweaked.

Any progression on this? I just purchased Hubitat and have 9 Somfy motorized blinds throughout the house. Having to use the Dimmer device for it to work.

Use the driver posted by @DeveloperDavidB . Work great on all my shades.

Awesome. Didn't see it until now. I see open and close works. Does percentage work? Set blind to 50%

It does work as percentage. Just be aware rule machines doesn't support motorized shade in %.
You can only control raise, lower, or stop but you can control the position as a dimmer instead of shade in RM.

FWIW... this device type is not fully compatible with Homebridge or verbally with Alexa.

When you attempt to Close the Curtains you receive this error in the logs.

[dev:12](http://192.168.7.201/logs#dev12)2019-04-06 01:32:18.391 pm [error](http://192.168.7.201/device/edit/12)groovy.lang.MissingMethodException: No signature of method: user_driver_E_Sch_Somfy_Z_Wave_Shades_and_Blinds_Multi_tile_68.setPosition() is applicable for argument types: () values: [] Possible solutions: presetPosition() (setPosition)

It would be awesome if someone could look into this issue and help!

Tried a bunch of the work-arounds discussed here. Similar Bali blinds using Somfy controllers; doesn't work.

Use generic dimmer, partially works, but no battery reporting, complicated UI/UX and painful work-arounds for voice control.

The generic driver above somewhat works, but doesn't work with shade controls or voice control.

Please Hubitat creators, this needs some love.

3 Likes

Quick question, as I'm looking at Bali blinds. I see threads here that talk about their Autoview, but Bali makes two kinds of motors - the Autoview (now listed as "Zwave plus") and the "easyview" with Radio Tech Somfy (RTS). Which is the better option for Hubitat integration?

thx! (from, the not-as techno as my hubby wife)...

Go with the z-wave option.

Hubitat can support z-wave, zigbee, telnet and IP-based devices.

I have a Graber blind in my office that uses a Somfy (Z-Wave) module. So far it's working fine. It's been in about a month. Got it at Zebra Blinds.

Download the Hubitat app