Skip to main content

Philips Hue Bridge

Philips Hue lights driven over the local CLIP v2 API on a Hue Bridge V2 (the square model). One GEM device represents one bridge. Each light you want GEM to control becomes a zone whose Address is that light's resource id; a Hue room or Hue zone becomes a zone whose Address carries a group: prefix.

Everything runs on the LAN. No Hue cloud account, no remote API, no internet path — pairing and control both happen against the bridge itself.

What this driver does and does not do

It switches lights on and off, sets brightness, colour and colour temperature, recalls Hue scenes, and mirrors on/off plus brightness back onto the zone.

It does not subscribe to the bridge's event stream, so a wall dimmer press or a change made in the Hue app is picked up on the next poll rather than instantly. And the brightness slider in GEM's standard light control does not reach this driver — read Brightness and the dimmer slider before you promise a customer a working slider.

Prerequisites

  • A Hue Bridge V2 (square). The round V1 bridge only speaks the older API and will not work.
  • Bridge firmware 1948086000 or newer — that is the release that added the CLIP v2 API.
  • The bridge and the GEM controller on the same LAN, with TCP 443 open from GEM to the bridge.
  • Physical access to the bridge during commissioning. Pairing requires pressing the round link button; there is no remote-pairing path.

The bridge serves a self-signed certificate. GEM accepts it as-is — you do not need to replace it. A firewall or inspection appliance that re-signs TLS in the middle will break the connection, so keep the bridge on a path that does not do that.

Setup

  1. Find the bridge IP. GEM has no Hue-specific discovery — the network scan finds open ports, not bridges — so get the address from the Hue app (Settings → My Hue System → Bridge), from your router's DHCP table (the client shows as a Philips/Signify device), or by opening https://discovery.meethue.com, which lists the bridges visible from your site's public IP. Give the bridge a DHCP reservation while you are there; every zone you create points at this address.
  2. Add the device. On Devices, add a device, give it a Name and Label, and set Driver to philips_hue. A driver panel appears with a short Before you start / Setup steps / Known quirks summary and a View integration guide link that opens this page inline.
  3. Fill in the connection attributes. Under Device Attributes, set Bridge IP Address. The remaining four sit behind Show 4 optional attributes and can stay at their defaults on a normal job — leave Application Key blank, you are about to mint it. There is also a Load sample: LAN setup (after pairing) button that fills the form with an example if you want to see the shape.
  4. Leave the command set alone. If Command Set is empty, GEM creates one named philips_hue and tells you so. The driver's commands are written into it the next time the device loads, and the device's Commands tab only appears once a command set is assigned.
  5. Save. The device will report disconnected — expected, it has no application key yet.
  6. Press and release the round link button on top of the bridge.
  7. Within about 30 seconds, run pair_bridge. Open the device's Commands tab, pick the bridge as the Test Device, and run pair_bridge with the test button. On success the bridge mints an application key, GEM stores it encrypted in the Application Key attribute, and the driver immediately reconnects — no manual reload needed. The reply shows <saved> rather than the key itself; that is deliberate, the key is never displayed back.
  8. List the lights. Still on the Commands tab, run get_lights. Each light comes back with an id (a UUID), a metadata.name (the name from the Hue app) and its current state. The id is what a GEM zone Address holds. Run get_groups the same way for Hue rooms and zones, and get_scenes for scenes.
  9. Create one zone per light. On Zones, add a zone, set Device to the bridge, and paste the light's id into Address. Choosing the device pre-selects the Lights subsystem and shows the address hint under the field. Pick a ControlLight (Switch) for on/off, Light (Dimmer) if you want the brightness readout (see the limitation below).
  10. Verify. Use Test Connection on the device form for a commissioning verdict, then switch a zone on and off from its control and watch the light.
Always set the zone Address

Zones are never created automatically here, and a zone saved with an empty Address is not skipped — GEM falls back to keying it by its internal record number. The driver then asks the bridge for a light whose id is that number, the bridge does not recognise it, and the zone silently never turns on and never reports state. If one zone in a room is dead, check its Address first.

Zone addressing

AddressTargets
1a2b3c4d-5e6f-…A single Hue light. Use the id from get_lights.
group:1a2b3c4d-…A Hue room or Hue zone. Use the id from get_groups.

Two things to get right:

  • Use the id field, not the legacy id_v1 number (/lights/3) and not the light's name. The device form's quick-start calls this the "rid" — same value, same UUID.
  • A group address must come from get_groups, which lists the bridge's grouped-light resources. A room's own id from the Hue app is a different resource and will not respond.

Attribute reference

Device

AttributeLabel in the formRequiredDefaultNotes
ipBridge IP AddressyesLAN address of the bridge. Without it the driver stops before connecting.
application_keyApplication Keyfor controlMinted by pair_bridge and stored encrypted. Sent on every request. Without it the driver connects to nothing and logs that the bridge is not paired yet.
portHTTPS Portno443Only change it if something in front of the bridge remaps the port.
status_intervalStatus Poll Interval (ms)no5000Gap between poll sweeps. 0 does not disable polling — it falls back to 5000.
devicetypePairing Device Typenogem-controller#defaultThe label the Hue app shows for this application key under Settings → Apps. Set it before pairing if you want a per-controller name on a multi-controller site.

The driver also honours a request_timeout attribute (milliseconds before a single bridge request is abandoned, 10000 by default) even though it is not offered on the device form — add it by hand on the Attributes tab if a slow link needs a longer window.

Zone

AttributeWritten byNotes
statedriveron or off, from the light's power state.
leveldriverBrightness 0-100, rounded to a whole number.

Both names are catalogued, so they autocomplete in the Attribute editor and can drive attribute triggers — for example, run a macro when a zone's level crosses a threshold.

Commands

CommandArgsWhat it does
onaddressTurns the light or group on.
offaddressTurns it off.
set_leveladdress, levelBrightness 0-100. Values outside the range are clamped and non-numeric input is treated as 0; fractions are passed through, the bridge accepts them. The write always carries the power state too, so set_level 0 turns the light off and any level above 0 turns it on.
set_coloraddress, hue, saturationHue 0-360 (wraps past 360), saturation 0-100. Converted to a CIE xy pair. Brightness is not touched. Lights with no colour capability ignore it.
set_color_tempaddress, mirekColour temperature in mireds, 153 (coolest) to 500 (warmest). Out-of-range and non-numeric values clamp to the nearest end — junk lands on 153, so check the value if a light unexpectedly goes cold. Tunable-white and colour lights only.
recall_scenescene_idActivates a Hue scene. Takes the scene's id from get_scenes and ignores the zone Address entirely, so a scene can be fired from a macro without a zone.
get_lightsLists every light: id, metadata.name, power, brightness, colour.
get_groupsLists the grouped-light resources behind Hue rooms and zones.
get_scenesLists scenes defined on the bridge.
get_bridgeBridge metadata — model, software version. Useful as a one-shot reachability check.
pair_bridgeMints and stores a new application key. Press the link button first.

The address argument is filled in for you when a command runs against a zone — the zone's own Address is used. You only pass one explicitly when running a command against the device from the Commands tab or from a macro that names no zone.

Colour is approximate

set_color converts hue and saturation through a single conversion that does not clamp to each light model's published colour gamut. Whites and mid-tones land where you expect; deeply saturated colours reproduce a little differently between a Hue Color bulb and a narrower-gamut fixture. For colours a customer will judge side by side, build the look in the Hue app as a scene and fire it with recall_scene.

Brightness and the dimmer slider

This is the one behaviour that surprises people on site, so plan around it:

  • Every brightness control in GEM — the Light (Dimmer) slider, the lights page, shortcut widgets, and the assistant's "dim the kitchen" phrasing — sends the zone verb level.
  • This driver implements brightness as set_level, and GEM does not translate one into the other. A slider drag against a Hue zone comes back as an unknown command and the light does not move.
  • The slider still displays correctly, because polling writes the zone's level back from the bridge. That combination — accurate readout, dead drag — is exactly what makes it look like a network fault when it is not.

What works today:

  • On and off from the Light (Switch) control, from a UI button, from macros and from triggers.
  • Brightness from a macro. Add a Command step in Macros, pick the bridge as the device, choose set_level, and set address to the light's id and level to the value you want. Preset macros (25 / 50 / 100) wired to buttons cover most of what a slider would have done.
  • Hue scenes. Build the scene in the Hue app, get its id from get_scenes, and fire it with a recall_scene command step. This is the better answer for whole-room looks anyway — one bridge call moves every light at once, with the bridge's own fade.

State polling

Every sweep the driver reads the full light list from the bridge and updates the zones bound to that device:

Zone attributeComes from
stateThe light's power state — on or off.
levelThe light's brightness, rounded to a whole number.

Details worth knowing when you size the poll:

  • The gap set by Status Poll Interval (ms) starts after a sweep finishes, and the driver pauses briefly between zones, so a bridge with a lot of zones cycles a little slower than the number suggests. On large sites raise the interval rather than fighting it — Hue lights rarely change without GEM knowing.
  • Zone attributes are only written when the value actually changed, so a steady room produces no attribute history churn.
  • group: zones are not read back. They accept commands, but nothing writes their state or level, so a group zone's control will look inert even while the lights obey it. Point the readout at one representative light if a room needs feedback.
  • Because state is polled, a zone can take up to one interval to catch up after GEM itself sends a command.

Troubleshooting

SymptomCheck
Device stays disconnected right after you create itExpected until pairing. Press the link button and run pair_bridge.
pair_bridge reports that the link button was not pressedPress the round button on top of the bridge, then run the command within about 30 seconds. Repeat presses are harmless.
Every command returns unauthorizedThe application key is missing or was deleted from Settings → Apps in the Hue app. Run pair_bridge again to mint a new one; it overwrites the stored key.
Connection refused, or a TLS errorConfirm the GEM host can reach the bridge on 443. The self-signed bridge certificate is fine on its own — an inspecting firewall that re-signs it is not.
One zone never changes stateIts Address is not a light id the bridge knows. Run get_lights and compare, watching for a group id used without the group: prefix, an id_v1 number, or a pasted name.
A whole room's zones stopped updatingRun get_bridge. If it answers, the bridge is fine and the addresses moved (a light was removed and re-added in the Hue app, which gives it a new id). If it does not answer, treat it as a network or power fault.
The device still shows connected while nothing respondsThe connected flag is set when the device loads and pairs; poll failures do not clear it. Use Test Connection on the device form for a live verdict — it reloads the device and reports what actually happened.
Brightness slider does nothingNot a fault. See Brightness and the dimmer slider above.
A colour looks wrong on one fixture but right on anotherGamut difference between light models. Use a Hue scene and recall_scene where exact reproduction matters.

For the driver's own log lines — pairing results, connect failures, the light count found at connect — see Logging.