Modern Forms Smart Fan
The Modern Forms Smart Fan driver controls Modern Forms / WAC Lighting smart ceiling fans — fan speed and, on fans fitted with an integrated light kit, that light's on/off and brightness. GEM talks to each fan directly over the fan's own local HTTP JSON API (port 80), so there is no Modern Forms cloud account and no hub in the middle — just the fan and GEM on the same network.
One Modern Forms GEM device represents one physical fan, addressed by its IP. Unlike some fan integrations, this driver does not discover fans or create their zones for you: you add the fan as a device, then create a fan zone (and a light zone, if the unit has a light) by hand and point each at that device. Which subsystem you put the zone in is what tells GEM whether it is the fan or the light — see Create the zones below.
Each fan is a separate device with its own Fan IP Address. The driver connects straight to that address and has no discovery, so the address must not change. Give every fan a DHCP reservation (or a static IP) before you add it, or GEM will lose the fan whenever DHCP hands it a new address.
Prerequisites
- A Modern Forms / WAC smart fan on the same local network as GEM.
- The fan commissioned through the Modern Forms mobile app at least once and joined to Wi-Fi. GEM controls a fan the app has already set up; it does not perform the initial Wi-Fi onboarding.
- A fixed IP for the fan — a DHCP reservation or static address — since the driver depends on a stable address.
Setup — adding the fan
- Open Devices, add a device, and choose the Modern Forms Smart Fan driver.
- Enter the fan's Fan IP Address. That is the only required connection field.
- Save and enable the device. GEM connects to the fan and begins polling it for state.
- Confirm the connection: the device should come online. You can also run the
get_statuscommand from the device's Commands tab — it reads the fan's current speed, light, and on/off state without changing anything, a quick reachability check.
Because there is no discovery to fall back on, a fan that changes IP simply goes offline in GEM. Set the DHCP reservation before you enable the device so the address you enter stays valid across reboots.
Create the zones by hand
The driver drives zones, not the device directly, and it decides whether a zone is the fan or the light purely from the subsystem the zone lives in:
- A zone in your Fans subsystem is treated as the fan.
- A zone in your Lights subsystem is treated as the light.
So for a fan with an integrated light you create two zones, both bound to the same Modern Forms device:
| Zone | Put it in subsystem | Zone Address | Controls |
|---|---|---|---|
| Fan | Fans | fan | Fan on/off and speed |
| Light (only if the unit has a light kit) | Lights | light | Light on/off and brightness |
To add each one, open Zones, create a zone in the right subsystem, bind it to the
Modern Forms device, and set its Address to fan or light as above. The two zones must have
different addresses so GEM can tell them apart.
If a fan zone is placed anywhere other than the Fans subsystem — or a light zone anywhere
other than Lights — the driver has no matching handler for it and its on/off/speed commands
do nothing. If commands to a zone are ignored, the first thing to check is that the zone is in the
correct subsystem. This also means renaming or removing the default Fans / Lights
subsystems will break control; keep zones under subsystems named fans and lights.
Only create a light zone for a fan that actually has an integrated light. Fans shipped without a light kit will simply ignore light commands.
Speed, state, and the 0–6 scale
Modern Forms fans run on an internal 0–6 speed scale. GEM maps that to the familiar 0–100 level you set from a dimmer-style control and to an Off / Low / Medium / High state label:
- The state reported back on the fan zone is
offat speed 0,lowat speed 1–2,mediumat 3–4, andhighat 5–6. - A
levelof 0–100 is scaled onto the 0–6 steps.0stops the fan; any level above 0 runs it at at least speed 1, so a low percentage never leaves the fan spinning at "off." - The
low/medium/highcommands run the fan at fixed steps — 1, 3, and 6 respectively. onsimply resumes the fan at its last speed (it does not force a specific step);offstops it.
The light zone
When you've created a light zone (in the Lights subsystem), it behaves like a normal dimmer:
levelsets brightness 0–100 directly.0turns the light off.low/medium/highset brightness to 25 / 50 / 100.onturns the light on at its last brightness;offturns it off.
Keeping state current
GEM polls the fan for its status on a fixed interval — every 10 seconds by default, tunable with the Status Poll Interval attribute (minimum 1000 ms) — and also re-reads the fan immediately after sending it a command, so a change you make from GEM (or the wall control or the app) shows up on screen without waiting for the next poll. Because the connection is polled rather than kept open, a fan that briefly drops off Wi-Fi is picked back up on the next successful poll.
Commands
Driver-declared commands appear on the device's Commands tab and can be used in macros, triggers, and on UI buttons. The fan and light verbs each take the target zone's address, which GEM fills in from the zone you pick; GEM routes the command to the fan or the light based on that zone's subsystem.
Fan and light control
| Command | Target | Action |
|---|---|---|
on | fan / light | Fan: run at the last speed. Light: turn on at the last brightness. |
off | fan / light | Fan: stop. Light: turn off. |
high | fan / light | Fan: speed 6. Light: brightness 100. |
medium | fan / light | Fan: speed 3. Light: brightness 50. |
low | fan / light | Fan: speed 1. Light: brightness 25. |
level (arg level) | fan / light | Set by percentage 0–100. Fan: scaled to the 0–6 steps (0 stops it). Light: brightness (0 turns it off). |
Diagnostics
| Command | Action |
|---|---|
get_status | Read the fan's live dynamic state (fan on/off and speed, light on/off and brightness) and sync it into the zones. Changes nothing. |
get_config (arg version) | Read the fan's configuration record. Takes no zone. Rarely needed — a service/diagnostic call. |
Attributes
Device
| Attribute | Type | Default | Description |
|---|---|---|---|
ip | string | — | The fan's LAN IP. Required. Enter it as Fan IP Address when adding the device. |
version | int | 3 | Modern Forms API version. Current firmware uses 3; leave it at the default unless an older unit needs a different value. |
status_interval | int | 10000 | How often, in milliseconds, GEM polls the fan for state (minimum 1000). |
GEM also records the fan's live state on the device as it polls — you don't set these:
| Attribute | Type | Description |
|---|---|---|
fan_speed | int | The fan's current raw speed, 0–6. |
light_level | int (%) | The integrated light's current brightness, 0–100. |
Zone
GEM populates these as it polls the fan; they're what UI controls, triggers, and automations read:
| Attribute | Applies to | Description |
|---|---|---|
state | fan zone | off / low / medium / high, derived from the running speed. |
level | light zone | The light's current brightness, 0–100. |
Both names are cataloged, so they autocomplete in the Attribute editor and can drive attribute
triggers — for example, fire a macro when a fan zone's state becomes high, or when a light
zone's level crosses a threshold.
Troubleshooting
| Symptom | Check |
|---|---|
| Device won't come online | Confirm the Fan IP Address is correct and reachable from GEM, and that the fan is powered and on Wi-Fi. Because there's no discovery, a wrong or changed IP is the most common cause — set a DHCP reservation. |
| Connection flips between online and offline | Usually weak Wi-Fi at the fan. Check the fan's signal strength in the Modern Forms app (aim for stronger than about −65 dBm) and improve coverage or move the access point closer. |
| Fan or light commands do nothing | The zone is almost certainly in the wrong subsystem — the fan zone must be under Fans and the light zone under Lights, or the driver has no handler for it. Also confirm each zone's Address is set and the fan and light zones use different addresses. |
| Light commands have no effect | The fan may have no integrated light kit — some down-rod models ship without one. Confirm the light works from the Modern Forms app before adding a light zone. |
| Speed changes feel coarse | Expected — the fan has only 6 speed steps, so a 0–100 level snaps to the nearest of those steps. |
See also
- Devices — adding and enabling the fan device.
- Zones — creating the fan and light zones by hand.
- Subsystems — the Fans and Lights subsystems that decide how a zone is controlled.
- Commands — running and scripting the fan and light commands.
- Attributes — the poll interval, API version, and live fan/light state.
- Macros and Triggers — automating fans and reacting to their state.