Somfy ZWave Blinds (Dimmer)

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.

I tried this driver; while seem to be able to talk to the shade & fetch info just ok, but it is throwing an error when I try to open/close/set position.

I even got hold of the driver code from ST and compared it what @DeveloperDavidB had posted in this thread. Everything checks out - only changes are color and replacing 'physicalgraph' with 'hubitat' (See comparison), so not sure why is it not working for me?

I am really struggling to have my shades work, so any help will be appreciated.

I'm in the same position as @yashvind . None of the driver codes work except the dimmer but I can only put the blinds up or down, they will not accept any position. Any update on a potential solution?

Though not fully resolved yet but I have made some progress. See details on this post. If you want, I can keep you apprised and help with the steps once I achieve full resolution.

1 Like

For anyone looking for a driver that works, I've taken a bit of time and done my own version and it works with all of the Graber roller shades that I have. Those include Bali, Somfy, Springs Window Fashions, and a few other names.

The driver works with Hubitat dashboards, Google Home integration (using community) and I would assume all other integrations. All position sets work as well i.e. setting the blinds to 50% on the dashboard sets them to 50%.

If you are using the Hubitat integration with Google Home and not the community version it will still not work saying open and close. This is not a limitation with the driver, but a limitation with how Hubitat's version of Google Home passes these parameters to Google. There's a number of posts on how to get the community version to correct this.

If anyone has issues with it please let me know.

I'll work on additional features and cleanup when I have time and I'll also work on a driver for the z-wave remote for Bali.

3 Likes