GE Ceiling Fan Switch Custom Device Type - Low, Med, High buttons w/no slider!

Hi everyone! I recently got this fan switch from Home Controls and it works great, but I really did not like the slider to control the fan speed. Neither did the wife, so it wasn’t passing the WAF (wife acceptance factor) test.

I used ST’s default dimmer switch device type to create a new custom device type that replaces the slider with 3 buttons - Low, Med, and High; AND a tile to show the current speed setting. Check it out:

If anyone has this device and would like the code to use for yourself, here it is:

(disclaimer: I’m not a coder, so please excuse any poor coding practices!)


Stupid question…

do you need a special kind of fan for this to work? I’m not sure I understand how it sends the spend control to the fan for a “drawstring” speed control.

Found a few pictures which is very interesitng

Google Picture

I might have to look at my wiring and see if they wired my fans like this. I currently have just a normal “on / off” switch installed. But this would be awesome!

Hi John… thanks for sharing the code!

If you can excuse me butting in, I have some ideas that are just humble optional suggestions…
I can delete this post immediately upon request.

1] Features

(a) May I suggest adding optional Device Preference Inputs (that the user can input using the Thing Preferences sub-tile), so that the user can configure their own custom speed values associated with Low, Med, High?
Add three lines of this syntax:

preferences {
    input "lowSpeed", "number", title: "Sample Input Title", description: "Define low speed value", defaultValue: 20, required: false, displayDuringSetup: true

(b) Personally, I would prefer still having the speed slider available in addition to the Low/Med/High preset buttons. Get the best of both worlds that way, I suppose: Instant speed selection + fine tuning.

2] Coding Style:

(a) A totally insignificant deal in a small program, but to gain a wee bit of modularity, I suggest that your methods for lowSpeed(), medSpeed(), highSpeed() should call “setLevel( number )”, rather than referencing the underlying zwave methods directly – redundantly.

This makes your code easier to port to a different device, such as a ZigBee based fan controller, since all the low level hardware stuff is isolated to as few method definitions as possible.

(b) The Device Type should really be of “capability.fanSpeed”, rather than “capability.switchLevel”, but that is something currently “out of our hands”, as we can’t add new Capabilities on the fly; so I have no problem with that choice. However, you can consider maximizing consistency by not adding any attributes that are not really necessary. Switch Level already includes “attribute: level”, you can use that in place of adding the new attribute “currentSpeed”.

Since, fundamentally, your Device Type is overloading the setLevel() command to set fan speed, the code is slightly cleaner if it commits to that overloading.

Just my 2c; hope I’ve been helpful rather than a nuisance; but let me know…
Have a good one!

…CP / Terry.


Hi @craig, there are no stupid questions!

No special fan is needed. I had two wall switches, one that turned on the fan and one turned on the lights. I replaced the light switch with a normal GE zwave on/off switch, and the fan switch with this new zwave fan switch from GE.

On the fan I leave the pull strings for the fan in the high position all the time, and the light on all the time. The zwave switches now control everything - fan speed and light on/off - from the new wall switches and ST.

If all you have is just the fan and no lights, the install is very easy. Where you have your normal on/off switch today there needs to be neutral wires. One from the fan and one coming from the breaker panel. They’re probably bundled up behind the switch.

You’ll need to add a jumper wire from that bundle of neutrals (white wires) to the neutral terminal on the new switch, you’ll connect power (black wire) coming from the breaker panel to the terminal marked Line on the new switch, the ground wire, and then the Load (black wire) from the fan to Load on the switch.

Again, leave the pull string switch in the high position and let the new GE switch handle speed changes.

That help?


@tgauchat, no problem Terry, suggestions are always welcomed and thanks for the comments.

I thought about adding preferences but the switch basically doesn’t fine tune, In other words, level 10, 15, 25 … and 30 are the same speed. I can’t remember the exact numbers off the top of my head, but as long as a number between 1 and 30 are used it will be considered low speed, 31 through 65’ish (I think) is considered medium, and anything above that is high. It’s like a dimmer but with only 3 dim levels.

I used the slider to painfully increment 1 step at a time until I found each point where the speed changed. Because of that, there was no need to keep the slider because it added no value for fine tuning and it took up screen space. If it acted and stepped like a normal dimmer, I certainly would have liked the slider to stay as well.

I agree about addressing the methods and calling setLevel. I did it that way because I wasn’t smart enough to figure out how pass along the level value correctly and debug messages without chewing through ST’s documentation, and just my lack of experience with this programming language while testing. Once it worked I celebrated with a beer, or two…

I used currentSpeed as a string value instead of the actual numerical value so I could update the tile with text. I’m sure there’s probably a better way, but I thought of that tile at the last minute and put that code together. Once it worked I celebrated with another beer :wink:

I’ll date myself and say it’s been a long while since I’ve coded - Cobol, CICS, Fortran77 were my days, but I enjoy learning new stuff. The developers that work in my organization just amaze me with what they can do today, and I wish I could learn just 10% of what they and others in the community can do.

I do appreciate the suggestions, thanks for sharing!


I must be of similar vintage, as my first Computer Science class was Fortran on a punch-card based mini-mainframe (the final year that machine was used), and my second was COBOL on a networked set of Commodore PETs.

Handling the numeric level attribute as a String for the tile can probably be done with an in-place data conversion method (I say “probably” because Groovy has weird strings that freak me out, not as consistent as Java). Earn another beer by trying “level.toString()”; and if that doesn’t work, try “Integer.parseInt(level)”…


1 Like

Ok, I’ll admit to that as well. Computer Science at Purdue a while back. I remember how excited we were when we stopped using cards and could submit jobs to the mainframe, run across campus to the only 132 character wide printer, wait in line to get our prints and see how it worked. I was a lot thinner back then…

Thanks for that suggestion Terry, I will certainly try that. It’s getting a bit late on the East Coast, so this will have to be done with some morning orange juice instead of a beer, but I did contemplate another!

1 Like

I graduated with Masters in Computer Sciemce in late 90’s back in India in one of the most elite institute and the only language we learnt then was COBOL, C, fortran and software like WORDSTAR. I saw the first Windows based PC when I migrated to US in 97. :wink:


Nice to see other “vintage” folk here too.
My first class had us writing COBOL and inputting via punch card.
The computer was an ICL System 4-30. State of the art transistorised computer!


Terry, AFAIK, ceiling fans are hardwired with just 3 speeds. Fan controls aren’t like regular dimmers, in fact regular dimmers aren’t designed to control motors. In ST before this new device type, the fan controls out there could be controlled using the standard dimmer device type. Doing so just meant that there were ranges that corresponded to low, medium and high. There is no fine tuning of a ceiling fan beyond that.

1 Like

Yah … you’re right. I guess I was optimistic that the use of the dimmer would add magic functionality. Some of the fancy new fans (Big Ass Fans?) are more sophisticated, but have their own controllers.

Thus John’s implementation is a convenient and clever hack – the longer term solution is we really need a new Capabilitycapability.fanSpeed” (which might even apply to HVAC (thermostats) as well).

Tagging: @Ben because I think he’s the official guy taking unofficial note of evolving capability requests. :wink:

Those are pretty cool, gotta show my wife. We live in Arizona and fans are a big deal.

They have 10 speeds.

1 Like

If you can afford $1200 a fan. They are really cool, but until my rich uncle gets out of the poor house, I’ll have to stick with regular ceiling fans.

1 Like

Nice job. It;s a lot more intuitive to use than the slider.

I did customize it for me though. I have the currentSpeed display “Off” when the fan is off. I just added the sendEvent to the off() method.

Thanks @twack, I appreciate that.

Love this, it is exactly what I was looking for and works great except for one thing. The Current Speed tile is not displaying anything, just stays blank. Any help would be appreciated.

I’m having the same issue current speed window is blank. Other then that it works great!! Thanks for sharing!

@wackware could you share your device type? Would like to have the window display off when fan is off. Thanks

@SFAJeff and @johnosstyn, would you mind logging out of the app, clearing any cache in Application Manager (Android), and logging back in to the app and checking again? When you turned on/off the fan, the tile still didn’t update?

When I get out of work I can also add the changes Twack made.