Flair (Smart Vents / Zoning)
Add room-by-room HVAC zoning to a single-stage forced-air system with Flair. Flair motorizes existing supply registers (Smart Vents), reads each room with a Puck sensor, and balances airflow to hit per-room set-points. GEM drives it through the Flair cloud API: open, close, or set a percentage on each vent; set a room set-point; and read room / puck temperature and humidity.
One Flair account is the GEM device. Each Flair vent, room, and puck becomes a GEM zone, addressed by a type-prefixed id so one device row can expose all three kinds of entity without ambiguity.
Authentication
Flair uses OAuth2 client-credentials. Your account is issued a client id and client secret; the driver exchanges them at the token endpoint for a short-lived bearer token and re-mints it automatically when it expires. There is no refresh token to manage.
To obtain credentials, request API access from Flair — email partners@flair.co (or use the
developer request form on flair.co) and reference the account the vents are registered to. Flair
issues a client_id / client_secret pair scoped to that account.
Flair migrated from /oauth/token (v1, no scopes) to /oauth2/token (v2, scoped). The driver
defaults to v2 with a full read/write scope list. If your credentials are a legacy v1
client, set OAuth Token URL to https://api.flair.co/oauth/token and clear the OAuth
Scope field.
Prerequisites
- A Flair account with a Puck gateway and at least one Smart Vent or room configured in the Flair app.
- OAuth2 client id + client secret from Flair (see Authentication above).
- Outbound HTTPS from the GEM server to
api.flair.co.
Setup steps
- Go to Devices → Add Device and choose the Flair (Smart Vents / Zoning) driver.
- Enter the OAuth Client Id and OAuth Client Secret Flair issued you.
- Set Temperature Unit to how you want room / puck temperatures expressed (
fahrenheitdefault, orcelsius). Flair stores Celsius internally; the driver converts. - Save. The driver mints a bearer token and verifies the account by listing structures.
- Run get_devices to enumerate structures, rooms, vents, and pucks with their zone addresses.
- Create a GEM zone per Flair entity and set the zone Address to the type-prefixed id (see Zone address format).
Attributes
Device
| Attribute | Type | Required | Description |
|---|---|---|---|
client_id | string | yes | Flair OAuth client id issued to your account. |
client_secret | string (secure) | yes | Flair OAuth client secret. Stored encrypted. |
temperature_unit | string | no | fahrenheit (default) or celsius — unit for room / puck temperatures and set_temperature. |
api_base | string | no | API base URL. Default https://api.flair.co. |
token_url | string | no | OAuth2 token endpoint. Default https://api.flair.co/oauth2/token; use /oauth/token for a legacy v1 client. |
scope | string | no | Space-separated scopes for the v2 token endpoint. Blank for a legacy v1 client. |
status_interval | int | no | Poll interval in ms. Default 60000, minimum 15000. |
Zone
Zones need only an Address. As it polls, the driver writes these read-only attributes based on the zone's entity type:
| Attribute | Applies to | Meaning |
|---|---|---|
state | vent, room | Vent: open / closed. Room: on / off (room active flag). |
level | vent | Percent open, 0–100. |
duct_temperature | vent | Supply-air temperature at the vent, in the configured unit. |
temperature | room, puck | Measured temperature in the configured unit. |
humidity | room, puck | Measured relative humidity (%). |
setpoint | room | Room target temperature in the configured unit. |
voltage | puck | Puck battery voltage. |
rssi | puck | Puck wireless signal strength. |
Zone address format
The zone Address is a type prefix plus the Flair entity id:
| Prefix | Entity | Example | Typical commands |
|---|---|---|---|
vent: | Smart Vent | vent:1234 | open, close, set_level, on, off |
room: | Room | room:5678 | set_temperature, on, off |
puck: | Puck sensor | puck:9012 | read-only (get_status) |
structure: | Structure (home) | structure:42 | set_structure_mode |
Run get_devices to list every entity's id, name, and ready-to-paste address.
Commands
| Command | Args | Notes |
|---|---|---|
get_devices | — | List structures, rooms, vents, and pucks with their zone addresses. |
get_status | address | Live state for one zone, or all zones when address is omitted. |
open | address | Vent: open fully (100%). |
close | address | Vent: close fully (0%). |
set_level | address, level | Vent: set percent open (0–100). |
on | address | Vent: open. Room: mark active. |
off | address | Vent: close. Room: mark inactive. |
set_temperature | address, value | Room: set the room set-point in the configured unit. |
set_structure_mode | address, mode | Structure: manual or auto (see below). |
Manual vs Auto mode
This is the single most important thing to understand about Flair.
- In Auto mode, Flair's own algorithm continuously re-positions vents to hit each room's
set-point. A
set_levelyou send will be overridden within minutes as the system rebalances. - In Manual mode, Flair leaves vents where you put them, so direct
open/close/set_levelcontrol holds.
Use set_structure_mode with mode=manual on the structure:<id> zone when you want GEM to
drive vents directly (for example, tying a vent to a GEM lighting/occupancy macro). Switch back
to auto to hand control back to Flair's balancing.
Known limitations
- Cloud-only. Flair exposes no documented local API; control depends on
api.flair.coand outbound internet from the GEM server. There is no LAN fallback. - Mechanical detents. Smart Vents physically stop near 0 / 50 / 100 percent. A
set_levelof 30 is accepted by the API but the louvers round to the nearest stop. - Set-points depend on structure mode.
set_temperaturewrites the room set-point, but whether it drives airflow depends on the structure's set-point mode and on the room being active. It has full effect when Flair is running its own balancing (Auto). set_structure_modevalue mapping is best-effort. Themanual/autovalues match Flair's documented structure mode; if your account model differs, verify against a live structure and adjust. The command fails gracefully (returns an error) rather than crashing.- No scene / schedule editing. The driver reads and controls live state; it does not create or edit Flair schedules or scenes.
Troubleshooting
| Symptom | Check |
|---|---|
invalid_client on connect | client_id / client_secret are wrong or not yet activated. Confirm the pair with Flair support. |
invalid_scope on token request | Legacy v1 client. Set OAuth Token URL to https://api.flair.co/oauth/token and clear OAuth Scope. |
get_devices returns empty lists | The account has no structures, or API access was not granted to these credentials. |
| Vent moves then snaps back | The structure is in Auto mode. Run set_structure_mode with mode=manual. |
| Room temperature never updates | Confirm outbound HTTPS to api.flair.co is allowed and status_interval is reasonable. |
Related Documentation
- Devices
- Zones
- tado° — a comparable cloud climate integration.