- Home
- Integrations
- Philips Hue
Integrations
Philips Hue from Shelly
Put Hue groups and scenes on a Shelly wall switch, locally through the bridge.
Updated August 2026
What this does
A customer with Hue lights in the living room and Shelly relays everywhere else has two apps and two ways of switching things on. This closes that gap from the Shelly side.
A virtual component in Shelly Smart Control becomes a Hue control: a switch that turns a Hue room on and off, or a button that recalls a scene. The Shelly talks directly to the Hue Bridge over the local network — no cloud on either side, no Home Assistant in between.
It also means a physical wall switch wired to a Shelly can drive Hue lights, which is the thing Hue itself makes awkward. Set the input to detached, point it at the virtual component, and an ordinary switch controls a bulb that has no wired switch at all.
Requirements
- A Hue Bridge V2 on the same network
- A reserved IP address for the bridge. The script points at an address; a DHCP change breaks it silently
- A Shelly device with scripting and virtual components — Gen3 or newer. Virtual components do not exist on Gen2
- A Shelly Premium subscription may be required depending on how many virtual components you create
Authorise on the bridge
The bridge does not accept commands from anything it has not been introduced to. Creating an authorised user takes a minute and is done once.
Philips documents the procedure at developers.meethue.com. In short: send a request to the bridge, press the physical button on the bridge within thirty seconds, and send it again. The second attempt returns a username string.
Keep that string. It goes into the script, and it is what authorises every command.
Find the group and scene ids
Hue addresses rooms and zones as groups, each with a number. Scenes have an id too, and a scene belongs to a group.
With the username in hand, ask the bridge what it has. Open this in a browser, substituting your values:
http:/api/YOUR-USERNAME/groupsThe response lists every room and zone with its id and name. The same works for /scenes and /lights.
Note down the group id for each room you want to control, and the scene ids you want on buttons. Both go into the script’s configuration block.
Create the virtual components
In Shelly Smart Control, open the device and go to Virtual components → Create virtual component.
For on and off: create a Boolean. It appears as a switch in the app, and the script sends the Hue group on or off when it changes.
For a scene: create a Button. Pressing it recalls the scene.
Name each one after what it does — “Living room lights”, “Evening scene” — and note its id. The ids go into the script, and a component named Boolean 200 is impossible to match to a room six months later.
The script
Install it on the Shelly, not on anything else. See how to add a script, and enable run on startup.
/**
* Control Philips Hue from a Shelly device.
*
* Virtual components in the Shelly app become Hue controls:
* a Boolean switches a Hue group on and off
* a Button recalls a Hue scene
*
* Requires a Gen3 device or newer — virtual components do not exist before that.
* Tested against Hue Bridge V2 using the local v1 API.
*
* One-way only: the Shelly sends commands and assumes the result. It is not
* told when a light is changed from the Hue app or a wall switch.
*/
// ===== CONFIGURATION =====
let BRIDGE = "192.168.1.50"; // Hue Bridge IP — must be a reserved address
let USER = "PASTE-YOUR-HUE-USERNAME-HERE";
// Boolean virtual components → Hue groups. One entry per switch.
// vc — the virtual component id, as shown in the app
// group — the Hue group id (a room or a zone)
let SWITCHES = [
{ vc: 200, group: 1 },
{ vc: 201, group: 3 }
];
// Button virtual components → Hue scenes.
// vc — the virtual button id
// group — the group the scene belongs to
// scene — the scene id from the bridge
let SCENES = [
{ vc: 210, group: 1, scene: "PASTE-SCENE-ID" }
];
// ===== END CONFIGURATION =====
function hue(path, body) {
let url = "http://" + BRIDGE + "/api/" + USER + "/" + path;
Shelly.call("HTTP.Request", {
method: "PUT",
url: url,
body: JSON.stringify(body)
}, function (result, code, message) {
if (code) print("Hue request failed: " + code + " " + message);
});
}
function findSwitch(component) {
for (let i = 0; i < SWITCHES.length; i++) {
if (component === "boolean:" + SWITCHES[i].vc) return SWITCHES[i];
}
return null;
}
function findScene(component) {
for (let i = 0; i < SCENES.length; i++) {
if (component === "button:" + SCENES[i].vc) return SCENES[i];
}
return null;
}
// A Boolean virtual component reports its new value as a status change.
Shelly.addStatusHandler(function (status) {
let cfg = findSwitch(status.component);
if (!cfg) return;
if (typeof status.delta.value === "undefined") return;
print("Hue group " + cfg.group + " → " + (status.delta.value ? "on" : "off"));
hue("groups/" + cfg.group + "/action", { on: status.delta.value });
});
// A Button virtual component emits an event instead.
Shelly.addEventHandler(function (event) {
if (!event.info || event.info.event !== "single_push") return;
let cfg = findScene(event.info.component);
if (!cfg) return;
print("Hue scene " + cfg.scene + " in group " + cfg.group);
hue("groups/" + cfg.group + "/action", { scene: cfg.scene });
});
print("Hue bridge control running — " + SWITCHES.length + " switch(es), " + SCENES.length + " scene(s)");Only the configuration block needs editing:
BRIDGE— the bridge’s reserved IP addressUSER— the username from the authorisation stepSWITCHES— one entry per Boolean, pairing its id with a Hue groupSCENES— one entry per Button, pairing its id with a group and a scene
Watch the console on the first run. Every failed request prints, which is considerably faster than guessing whether the problem is the address, the username or the group id.
Tips & best practices
- Reserve the bridge’s IP address first. It is the single most common reason a working setup stops working weeks later.
- Use groups rather than individual lights. A group survives a bulb being replaced; a light id does not.
- Detach the physical input on the Shelly so the wall switch drives the virtual component instead of the relay. That is what puts Hue on a real switch.
- Do not expect state back. Build the customer’s expectations around one-way control, or the first mismatch becomes a support call.
- Keep the username out of screenshots. It is a credential, and it appears in every URL the script builds.