Ikea Blinds

Post 35 has a method for pairing, and post 44 has the driver. Gateway not useful or required.

1 Like

For those looking at these blinds and FYI.. I came across this Video on YouTube the other day.. it's not the best BUT it does show how these can be resized slightly to improve fitment.

Glad someone else experimented first :wink: Frankly if it were me, I would have also taken some of the 'dead' space of the other side of the roller while I was at it so they are balanced/centered but also to cut down that gapping on the edge... I don't see any good reason why Ikea left an inch of bare roller on either side.

2 Likes

I stopped at my local Ikea today even though only 2 sizes are listed online.

They had EVERY size available. The prices were exactly as listed above.

I picked up 3 of the 48” blinds and hopefully will have time to install them tomorrow. It looked like they had at least a handful of every size in stock.

1 Like

Their website has always been so unreliable when it comes to stock with my kinda-local store (45 mins away). Thanks for your post, it gives me hope and I think I’ll take a drive over there in the morning to see if I can snag a set (or three)

Same at the IKEA in West Chester Ohio, was there today.



1 Like

I got 3 blinds all mounted and set up due to the great info in this thread.

In the package:
1 shade
2 mounting brackets
1 battery pack
1 USB A > Micro USB cable
1 Tradfri repeater - Zigbee
1 Remote Button - Zigbee

There are no screws in the package for the mounting brackets. You need 4 screws for each set of shades as there are 2 brackets each.

Step 1 - charge the battery pack. It’s 2,600 MAh and reports I’ve read state it should ‘last several months on a charge’.

Step 2 - Pair the Tradfri repeater in an outlet relatively close to the shade. To pair: Plug in the repeater into the USB plug and then into your outlet. The light will come on steady. To get it in pairing mode, with the repeater plugged in, use a safety-pin/sewing needle and insert it into the small hole next to the USB socket, you will feel the reset button and hold that down with the pin for 10-15 seconds. Remove the pin/needle and the white LED should start to blink. Then set your Hub to Zigbee discovery.

Step 3 - Mount/install the shade hardware - pretty basic and quick

Step 4 - Insert the battery pack into the blinds. There are two small buttons to the left of the battery door that manually operate the shade up and down.

Step 5 - Install the User Driver from @Ryan780 (thank you @Ryan780 ! ) which can be copied from this post (updated to version with battery reporting): Ikea Blinds - #120 by Ryan780

Step 6 - Pair the shade by following @Kev ‘s post quoted here. Remember to use the driver from step 5. After the LED on the blind turns on, set your Hub to Zigbee Pairing mode.

Step 7 - Set the Max Open and close states for the shade. Get the shade where you want it to be ‘most Open’ either via the manual buttons next to the battery or by using Hubitat device page/dashboard. Then double-tap the down button on the shade to the left of the battery pack. The shade will move up and down 1 CM if it was set properly. This now is equal to ‘100’ open for the shade.

So far I’m really pleased and these have boosted the WAF in our home!

11 Likes

It’s all about that Wife Acceptance Factor! lol

I’ve got the three measurements I need, heading to my local location in the morning. Looks like I’ll need to hack off an inch from each one (46.75” is my office window, bedroom windows are 22.75”)

3 Likes

@morningz

2 Likes

Yup! Watched that the other day, thanks!

1 Like

Our household has been really enjoying the Ikea shades so far!

It looks like the creator of the SmartThings driver added the ability to see battery percentage. I tried to port this over to the Hubitat driver and failed spectacularly because I'm not a developer. :slight_smile:

Are there any kind developers out there who would be willing to help me make two modifications to this Hubitat driver?

  1. Add battery percentage to the Hubitat driver - as you can see in the Smart Things driver: https://raw.githubusercontent.com/a4refillpad/Ikea/master/devicetypes/IKEA-window-blinds

  2. Add the ability to turn off debug logging, as these blinds are pretty chatty in the logs (battery level is more important to me, however)

Thank you very much to anyone who even considers this on my behalf!

5 Likes

Try this driver. All I did was add the battery %. I didn't go back through to make make any of the other changes. I did confirm it compiles in Hubitat but since I don't have the blinds, I can't test it.

/**
 *
 *
 *	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.
 *
 *  
 *  first release for IKEA smart window blinds for hubitat adapted from the driver for ST by Wayne Man
 */
import hubitat.zigbee.zcl.DataType

metadata {
    definition(name: "IKEA Window Blinds", namespace: "ryan780", author: "ryan780", ocfDeviceType: "oic.d.blind", mnmn: "SmartThings", vid: "generic-shade") {
        capability "Actuator"
        capability "Configuration"
        capability "Refresh"
        capability "Window Shade"
        capability "Health Check"
        capability "Switch Level"
		capability "Battery"					

        command "pause"
        
       	attribute "lastCheckin", "String"
		attribute "lastOpened", "String"

		fingerprint inClusters: "0000,0001,0003,0004", manufacturer: "IKEA of Sweden", model: "FYRTUR block-out roller blind"
    }
}

private getCLUSTER_BATTERY_LEVEL() { 0x0001 }
private getCLUSTER_WINDOW_COVERING() { 0x0102 }
private getCOMMAND_OPEN() { 0x00 }
private getCOMMAND_CLOSE() { 0x01 }
private getCOMMAND_PAUSE() { 0x02 }
private getCOMMAND_GOTO_LIFT_PERCENTAGE() { 0x05 }
private getATTRIBUTE_POSITION_LIFT() { 0x0008 }
private getATTRIBUTE_CURRENT_LEVEL() { 0x0000 }
private getCOMMAND_MOVE_LEVEL_ONOFF() { 0x04 }

private List<Map> collectAttributes(Map descMap) {
	List<Map> descMaps = new ArrayList<Map>()

	descMaps.add(descMap)

	if (descMap.additionalAttrs) {
		descMaps.addAll(descMap.additionalAttrs)
	}

	return descMaps
}

// Parse incoming device messages to generate events
def parse(String description) {
    log.debug "description:- ${description}"
    def now = new Date().format("yyyy MMM dd EEE h:mm:ss a", location.timeZone)
    //  send event for heartbeat    
    sendEvent(name: "lastCheckin", value: now)
    if (description?.startsWith("read attr -")) {
        Map descMap = zigbee.parseDescriptionAsMap(description)
        if (supportsLiftPercentage() && descMap?.clusterInt == CLUSTER_WINDOW_COVERING && descMap.value) {
            log.debug "attr: ${descMap?.attrInt}, value: ${descMap?.value}, descValue: ${Integer.parseInt(descMap.value, 16)}, ${device.getDataValue("model")}"
            List<Map> descMaps = collectAttributes(descMap)
            def liftmap = descMaps.find { it.attrInt == ATTRIBUTE_POSITION_LIFT }
            if (liftmap && liftmap.value) {
                def newLevel = zigbee.convertHexToInt(liftmap.value)
                levelEventHandler(newLevel)
            }
        } else if (!supportsLiftPercentage() && descMap?.clusterInt == zigbee.LEVEL_CONTROL_CLUSTER && descMap.value) {
            def valueInt = Math.round((zigbee.convertHexToInt(descMap.value)) / 255 * 100)

            levelEventHandler(valueInt)
        }
		if (descMap?.clusterInt == CLUSTER_BATTERY_LEVEL && descMap.value) {
            log.debug "attr: ${descMap?.attrInt}, value: ${descMap?.value}, descValue: ${Integer.parseInt(descMap.value, 16)}"
            sendEvent(name: "battery", value: Integer.parseInt(descMap.value, 16))
        }
    }
}

def levelEventHandler(currentLevel) {
    def lastLevel = device.currentValue("level")
    log.debug "levelEventHandle - currentLevel: ${currentLevel} lastLevel: ${lastLevel}"
    if (lastLevel == "undefined" || currentLevel == lastLevel) { //Ignore invalid reports
        log.debug "Ignore invalid reports"
    } else {
        sendEvent(name: "level", value: currentLevel)
        if (currentLevel == 0 || currentLevel == 100) {
            sendEvent(name: "windowShade", value: currentLevel == 0 ? "open" : "closed")
        } else {
            if (lastLevel < currentLevel) {
																 
												  
                sendEvent([name:"windowShade", value: "closing"])
            } else if (lastLevel > currentLevel) {
                sendEvent([name:"windowShade", value: "opening"])
            }
            runIn(1, "updateFinalState", [overwrite:true])
        }
    }
												  
}

def updateFinalState() {
    def level = device.currentValue("level")
    log.debug "updateFinalState: ${level}"
    if (level > 0 && level < 100) {
        sendEvent(name: "windowShade", value: "partially open")
    }
}

def supportsLiftPercentage() {
    device.getDataValue("manufacturer") != "Feibit Co.Ltd"
}

def close() {
    log.info "close()"
    zigbee.command(CLUSTER_WINDOW_COVERING, COMMAND_CLOSE)

}

def open() {
    log.info "open()"
    zigbee.command(CLUSTER_WINDOW_COVERING, COMMAND_OPEN)
}

def setLevel(data, rate = null) {
						   
    log.info "setLevel()"
    def cmd
	data = data.toInteger()
    if (supportsLiftPercentage()) {
        cmd = zigbee.command(CLUSTER_WINDOW_COVERING, COMMAND_GOTO_LIFT_PERCENTAGE, zigbee.convertToHexString(data, 2))
    } else {
        cmd = zigbee.command(zigbee.LEVEL_CONTROL_CLUSTER, COMMAND_MOVE_LEVEL_ONOFF, zigbee.convertToHexString(Math.round(data * 255 / 100), 2))
    }

    return cmd
}

def pause() {
    log.info "pause()"
    zigbee.command(CLUSTER_WINDOW_COVERING, COMMAND_PAUSE)
}

/**
 * PING is used by Device-Watch in attempt to reach the Device
 * */

def ping() {
       return zigbee.readAttribute(CLUSTER_BATTERY_LEVEL, 0x0021) // Read the Battery Level
}

def refresh() {
    log.info "refresh()"
	
    def cmds
    if (supportsLiftPercentage()) {
        cmds = zigbee.readAttribute(CLUSTER_WINDOW_COVERING, ATTRIBUTE_POSITION_LIFT)
    } else {
        cmds = zigbee.readAttribute(zigbee.LEVEL_CONTROL_CLUSTER, ATTRIBUTE_CURRENT_LEVEL)
    }
    return cmds
}

def configure() {
    // Device-Watch allows 2 check-in misses from device + ping (plus 2 min lag time)
    log.info "configure()"
    sendEvent(name: "checkInterval", value: 2 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
    log.debug "Configuring Reporting and Bindings."

    def cmds
    if (supportsLiftPercentage()) {
        cmds = zigbee.configureReporting(CLUSTER_WINDOW_COVERING, ATTRIBUTE_POSITION_LIFT, DataType.UINT8, 0, 600, null)
    } else {
        cmds = zigbee.levelConfig()
    }
    return refresh() + cmds
}

def setPosition(value){
	setLevel(value)
}
5 Likes

Thank you! I will try a bit later today when I’m at a PC. I tried on mobile and the driver functioned (blinds operated the same as before), with no errors in the log. But I’m not seeing any battery info in the logs, on the device page, or on a dashboard where I added the shade as a battery device.

It’s most likely user error on my part, made worse by trying to do this on mobile, so I’ll try again a bit later.

Thank you, again! I very much appreciate your time and effort on this!

I can't stress enough how much I appreciate your efforts.

Unfortunately the battery level doesn't appear to be displayed in Hubitat.

  • I added the driver
  • loaded the driver on the device page
  • hit configure
  • I don't see any errors in the logs.

I have a feeling that it's able to grab the battery level, but it's not displaying that level for some reason. This is an uneducated guess, however.

  • 'Battery level' does not on the device page as an attribute (see attached screenshots for what does display on the device page).
  • It doesn't show up in RM4 or in dashboard as an attribute.
  • Adding a battery tile to dashboard for the shade just shows "???"

If there's anything else I can do to help you debug, please let me know. I am very much aware that you don't have the shades to test with, and you have been volunteering your time thus far which I am grateful for.

Thank you, again!

Genius. I just wish those Farter Blinds came in different colors...

I've just tried @Ryan780 updated driver, the battery level seems to work for me.

Many thanks again :+1:

3 Likes

Oooh! Nice! I’ll try unpairing and repairing the blinds to see if I can get the battery level to work for me.

They’re noisy too :wink: at unexpected times. Blame the dog.

2 Likes

Seriously. Are they really noisy and not in the “blame the dog” sort of way which I’ve been known for? Not sure if the wife would go for that...

I got the drivers to work and was able to use Hubitat to close and open the blinds. I also got the remote it came with to pair but, no drivers. Does anyone have drivers for the remote itself?

Has anyone also gotten this added to Google Home. When setting up Hubitat it only sees my light switches and not these shades.

Not that I’m aware of, at least with Hubitat. But any standard Zigbee/zwave remote could be swapped out to control them through Hubitat.