Skip to main content
Version: 4.2 (beta)

Hue

HSYCO integrates Philips Hue lights, sensors, switches, rooms and Hue Secure devices through the bridge's local CLIP v2 API.

The driver talks to the bridge over HTTPS only, and receives state changes as push events rather than by polling, so lights and sensors report within about a second instead of at the polling interval.

Requirements​

  • A Hue Bridge Pro, or a square Hue bridge (v2 hardware) with software version 1948086000 or later. If a v2 bridge reports an older version, update it from the Hue app.
  • The original round Hue bridge (v1 hardware) does not implement the CLIP v2 API, cannot be updated to a version that does, and is no longer supported. See Upgrading from HSYCO 4.1.
  • The bridge must be reachable on the local network on TCP port 443.

HSYCO Configuration​

Add a HUE I/O Server in the I/O Servers section of the Settings and set its parameters:

High Availability​

  • Shutdown when inactive: defaults to false.

Options​

IDDefaultValuesDescription
ipaddress<ip_address>connect to the bridge at this fixed address, and never search for it. See Bridge discovery
mac<mac_address>identify the bridge by its MAC address and locate it on the network. Recommended when the bridge address is assigned by DHCP
startupeventsfalsetruegenerate IO events also during the driver's start-up phase
falsestart generating events only after HSYCO is aligned with the current status of the system
pollinterval300n > 0the interval, in seconds, of the full resynchronization with the bridge. This is a safety net only — normal operation is event-driven
resourcesallallexpose every supported resource family
<list>a comma-separated subset of lights, sensors, switches, groups, scenes, secure
sensorstruefalsedeprecated, kept for compatibility: equivalent to omitting sensors from resources
idmodev1v1lights keep the numbers they had in the CLIP v1 API, so that projects migrated from HSYCO 4.1 keep working. See Identifiers
uuidresources are addressed by their CLIP v2 UUID
poweruppowerfailafter a power loss every capable light returns to the state it had, and one that was off stays off. See Power-on behaviour
last_on_statethe same, except that a light that was off comes back on in its last on state
safetyevery capable light comes on at full brightness in warm white
(empty)leave the power-on behaviour of the lights untouched
colorloopmodeeffecteffectthe colorloop datapoint activates the closest effect the light supports
offthe colorloop datapoint is accepted but does nothing
discoverylocallocalfind the bridge by mDNS only. The driver never connects outside the local network
cloudalso query Philips' cloud discovery service if mDNS finds nothing. Requires Internet access
offno automatic discovery: use ipaddress, or the address remembered from the last successful start

Setup​

The first time HSYCO connects to the bridge, an authentication procedure is required. Configure the HUE I/O Server as described above and restart HSYCO. After a few seconds the datapoint authentication of the I/O Server is set to 1. At this point you have 60 seconds to press the button on the Hue bridge. From then on HSYCO stores the application key and the procedure is not needed again.

N.B. the application key is stored in bridge.ini, in the directory named after the ID assigned to the HUE I/O Server. Changing the ID requires performing the authentication procedure again.

An I/O Server upgraded from HSYCO 4.1 keeps the key it already had, and does not have to be paired again. See Upgrading from HSYCO 4.1.

Bridge discovery​

The driver operates entirely on the local network by default. Nothing it does requires Internet access: the CLIP v2 API is served by the bridge itself, and the certificate authorities used to validate the bridge are embedded in the driver, so no certificate or revocation server is contacted either. The only exception is the optional cloud discovery service described below, which is not used unless it is explicitly enabled.

How the bridge is located depends on which of ipaddress and mac you set:

ConfigurationBehaviour
ipaddressconnect to that address, and only that address. The bridge is never searched for
macidentify the bridge by its MAC and locate its current address. Follows the bridge when its address changes
bothconnect to ipaddress, but refuse it if the unit answering there is not the one with that MAC
neitheruse the address remembered from the last successful start, then search the network and take the bridge that no other I/O Server has paired with. See Adding a second bridge

Which one to use​

Set ipaddress when the bridge has a fixed address or a DHCP reservation. This is the most predictable configuration: if the bridge does not answer there, the driver reports the failure and keeps retrying that address. It will not look elsewhere and will not connect to a different bridge.

Set mac when the bridge address is assigned by DHCP and can change. The MAC address is printed on the underside of the bridge and never changes, so it identifies the unit for as long as you own it. The driver derives the bridge ID from it — the bridge ID is the MAC with fffe inserted in the middle, so 00:17:88:25:b8:f8 becomes 001788fffe25b8f8 — and matches that against the bridges answering on the network.

With mac set, a change of address is recovered from automatically, typically within about 15 seconds, without restarting HSYCO. The application key, the datapoint numbering and every project reference are preserved, because they belong to the bridge rather than to its address.

Whichever option is used, the bridge ID at every candidate address is verified before the driver connects. A different bridge answering at the expected address is detected and refused rather than adopted.

How the search works​

When the address has to be found, the driver tries, in order:

  1. the address at which the bridge answered last time, remembered across restarts;
  2. mDNS on the local network;
  3. Philips' cloud discovery service — only if discovery=cloud is set.

Philips deprecated UPnP/SSDP discovery and disabled it in 2022, so mDNS is the only local method still supported. It requires bridge firmware 1.23 or later, and the HSYCO server to be on the same subnet as the bridge — multicast traffic does not cross routers or, usually, VLANs. Setting discovery=off together with mac therefore defeats the purpose, and the driver logs a warning if you do.

A bridge that stays missing is searched for with a widening delay between attempts, up to five minutes, so that one left switched off does not cause continuous multicast traffic.

Keeping discovery local​

The discovery option controls this:

ValueBehaviour
local(default) mDNS only. No connection is ever made outside the local network
cloudmDNS first, then Philips' cloud service at https://discovery.meethue.com if mDNS found nothing
offno automatic discovery at all: the bridge must be at ipaddress, or at the address remembered from last time

discovery=cloud is opt-in because that service requires the HSYCO server to reach the Internet, only works if the bridge has itself contacted the Hue cloud recently, and is rate limited by Philips to one request every 15 minutes per public IP address. It is useful in one case only: a routed network where the bridge is reachable by unicast but multicast does not cross the segment boundary. Setting ipaddress solves that case too, without leaving the network.

With discovery=cloud, the service may refuse the request:

Initialization failed - the Hue discovery service is rate limited to one request every 15 minutes per network, and has refused this one (HTTP 429)

This happens when two or more HSYCO servers on the same network both query it: they share a public IP address, so Philips counts them as a single client and refuses the second request. It is only reached if mDNS already failed — check that the HSYCO server is on the same subnet as the bridge, or set ipaddress.

Adding a second bridge​

More than one Hue bridge can be used from the same HSYCO server, with one HUE I/O Server for each.

When a newly configured I/O Server has neither ipaddress nor mac set, it searches the network and then picks the bridge that no other I/O Server is already paired with. So adding a second bridge normally needs no configuration at all: create the I/O Server, start it, and press the link button on the new bridge when the log asks for it. The log names the bridge it is asking about:

No application key stored for bridge 001788fffe25b8f8 at 192.168.1.42 - press the link button on that bridge within 60 seconds

If the choice is not obvious, the driver refuses rather than guessing, and says why:

  • every bridge found is already in use — it lists them with the I/O Server that owns each one;
  • more than one bridge is free — it lists those, and asks you to set ipaddress or mac to say which one this I/O Server should use.
caution

Set up one new I/O Server and bridge at a time. A bridge is recorded as being in use only once its I/O Server has successfully paired with it, so two I/O Servers configured and started together, with two unpaired bridges available, can both choose the same one. Start the first, complete its pairing, and only then configure the second.

An I/O Server that already knows its bridge is unaffected by any of this: it goes straight to the address it used last time, and only searches the network if the bridge is not there.

Using one bridge with several HSYCO servers​

A single Hue bridge can be used by more than one HSYCO server, and by the Hue app at the same time. Each HUE I/O Server obtains and stores its own application key, so the pairing procedure described in Setup has to be performed once per I/O Server — pressing the bridge button once does not authorize the others.

Security​

The connection to the bridge is always HTTPS, with full certificate validation against the two Philips Hue root certificate authorities, and with the certificate's common name checked against the bridge ID. There is no option to disable validation and no fallback to plain HTTP.

If the driver reports a certificate error against a genuine Hue bridge, make sure automatic updates are enabled on the bridge, or update it manually by connecting to it with the Hue app: a small number of early bridges shipped with self-signed certificates and have since been updated.

Upgrading from HSYCO 4.1​

In HSYCO 4.2 this driver was rewritten on the Hue CLIP v2 API. The datapoints and commands of the previous version are unchanged, and an existing installation is upgraded in place: no re-pairing and no renumbering.

The first time the new driver starts it takes over the state the previous one had left behind:

  • the bridge username stored by the previous driver is adopted as the application key and written to bridge.ini. The two are the same value — what CLIP v1 called the username is what CLIP v2 calls the application key, and the bridge already holds it — so the button on the bridge does not have to be pressed again;
  • light numbers are unchanged, because the numbering the previous driver used is the one the bridge still reports for each light, and the new driver reads it from there;
  • the old persistent variable is left in place and ignored.

Nothing has to be done by hand, and this happens only when no HUE I/O Server has a bridge.ini yet.

What changed​

  • Rooms, zones, scenes, switches, dials and Hue Secure devices are now supported, as well as lights and motion sensors. See the datapoint sections below.
  • State arrives as push events instead of polling, so changes are reported in about a second. The pollinterval option still exists but is now the interval of a background safety resynchronization, and its default has changed from 10 to 300 seconds.
  • The master option is no longer available. Its purpose — restoring lights to their previous state after a power loss — is served better by the new powerup option, which is enforced by the lamp itself. See Power-on behaviour.
  • The colorloop datapoint still exists, but the effect behind it is different: Philips removed the color loop from the API. See Color loop.
  • light.<n>.on = flip now works. It was documented by the previous driver but had no effect.
  • The rgb and xy datapoints are now comma separated rather than semicolon separated. See Color.
  • The dimmer datapoint reports 99% correctly. The previous driver reported it as 100%.

Bridge v1 is no longer supported​

The original round Hue bridge does not implement the CLIP v2 API and cannot be updated to a firmware that does. An I/O Server pointing at one refuses to start and logs:

Initialization failed - bridge software version <n> does not support the CLIP v2 API, which requires 1948086000 or later. Update the bridge from the Hue app; the original round bridge cannot be updated to a supported version and is not usable with this driver

The bridge has to be replaced with a current one. Lights are moved across by resetting them and adding them to the new bridge, or with Touchlink.

The bridge.ini file​

Everything the driver has to remember between restarts is kept in bridge.ini, in the state/drivers/hue/<io_server_id> directory, where <io_server_id> is the ID of the HUE I/O Server in lower case: the bridge application key and address, and the numbers used in datapoint names.

Each HUE I/O Server has its own file, so its entries don't carry the I/O Server ID:

# HSYCO Philips Hue API v2 driver
#
# The light, sensor, switch, group and scene numbers below are the ones
# used in datapoint names. They may be edited to renumber a resource;
# changes are applied the next time the I/O Server is restarted.
#
# The appkey entries are secrets: treat this file accordingly.

appkey = sFlEGnMAFXO6RtZV17aViNUB95G2uXWw64texDzD
address = 192.168.1.23
bridgeid = 001788fffe25b8f8
light.1 = c6b028c8-076e-4817-92b1-bcb0cbb78783
light.2 = 39a1b2c3-4d5e-6f70-8192-a3b4c5d6e7f8
sensor.5 = 73db1290-5b13-4494-ad58-a7fe5415039f
group.2 = 708d8a89-5d05-408f-b43c-830fbff8316e
caution

The appkey entries give full control of the bridge and its lights. Philips documents the application key as a secret. The driver restricts the file to its owner when writing it; keep it out of backups and support bundles that are shared, and do not copy it between installations that should be independently authorized.

Renumbering a resource​

The numbering is keyed by number, so the file reads as "light 3 is this bulb" and can be edited to make the numbering match a project. Change the number on the left of an entry, then restart the I/O Server.

Two resources cannot be given the same number: the file format does not allow a duplicate key, and the driver logs an error if it finds one.

Edits are noticed within a few seconds. A changed address or appkey is adopted immediately, without a restart.

A changed number cannot be applied to a running I/O Server, because the datapoint names come from it and renaming them underneath a project would leave every reference pointing at the wrong resource. The I/O Server therefore restarts itself, and comes back using the new numbering:

state/drivers/hue/<io_server_id>/bridge.ini: the resource numbering of this I/O Server was changed, restarting to apply it

Each I/O Server only checks its own file, so editing it restarts only the I/O Server it belongs to; the others keep running.

Losing the file​

If bridge.ini is deleted, the driver has to pair with the bridge again — see Setup — and numbers every resource from scratch, which will not necessarily reproduce the previous numbering. Include it in your configuration backups.

Where the file comes from​

A bridge is written into this file only once its I/O Server has actually paired with it, so a pairing that was never completed does not leave the bridge marked as in use. This is also what lets a new I/O Server tell which bridges on the network are still free — see Adding a second bridge.

If no HUE I/O Server has a bridge.ini yet when the driver starts, one is created: on an installation upgraded from HSYCO 4.1 it picks up the existing bridge credentials, as described in Upgrading from HSYCO 4.1, and otherwise it is filled in as the driver pairs with the bridge and discovers its resources. An installation that already has a bridge.ini is never overwritten.

Identifiers​

The CLIP v2 API identifies every resource by a UUID, while HSYCO addresses resources by a short number. The driver assigns that number the first time it sees a resource and stores the mapping permanently in bridge.ini, so a number never changes once given.

Lights keep the number they had in the CLIP v1 API, which the bridge still reports for them. That is what allows a project written for HSYCO 4.1 to keep working: the previous version of this driver published lights and nothing else, so light.3 still refers to the same bulb. A light added since has no such number and is given the lowest free one, which the log records.

Everything else is numbered from 1 within its own kind. Switches, sensors, contacts, cameras, speakers, rooms, zones and scenes were not published by the previous version, so there is no earlier name to preserve — and inheriting the v1 numbers would import their oddities, since v1 counted switches and motion sensors in one series and rooms among all the groups.

Each kind of device is numbered independently, so the first speaker is speaker.1 whether or not there are motion sensors, and adding a device of one kind never shifts the numbers of another. In bridge.ini each kind has its own set of entries:

light.3 = …
sensor.1 = …
switch.1 = …
switch.2 = …
speaker.1 = …

The UUID of each resource is always published on the .uuid datapoint, so the mapping can be inspected at any time.

Datapoints — I/O Server​

IDValueR/WDescription
connectiononlineRconnection established
offlineRHSYCO can't connect to the bridge. Everything the bridge serves is unreachable while this lasts: see Reachability
authentication1Rthe Hue bridge is waiting for the authentication procedure to be performed
0Rdefault value
touchlink1Wstart a Touchlink scan: claim the nearest light. See Touchlink
1Ra Touchlink scan is running
0Rno scan is running

Datapoints — lights​

Each bulb is assigned an ID by the driver as described above. The driver generates several datapoints for each bulb, having the prefix light.<n>.

IDValueR/WDescription
light.<n>.on1R/Wthe light <n> is on / turn on light <n>
0R/Wthe light <n> is off / turn off light <n>
flipWinvert the state of light <n>
light.<n>.reachable1Rthe light <n> is connected to the bridge
0Rthe light <n> is out of reach, powered off, or still being added to the network
light.<n>.brightness1 ... 254R/Wthe brightness of light <n>
light.<n>.dimmeroffR/Wthe light <n> is off / turn off light <n>
1% ... 100%R/Wthe light <n> is on at the reported brightness / turn on and set brightness
onWturn on light <n> and set it to its last state before going off
light.<n>.rgb(1)<r>,<g>,<b>Rthe color of light <n>, whether it is on or off, e.g. "12,100,255"
Wset the color of light <n>. The light is not turned on. See Color
<r>,<g>,<b>,onWset the color and the state in one write, with on or off as the last field
onWturn on light <n>
offWturn off light <n>
flipWinvert the state of light <n>
light.<n>.hue(1)0 ... 65535R/Wthe color hue of light <n>. See Color
light.<n>.saturation(1)0 ... 254R/Wthe color saturation of light <n>. See Color
light.<n>.xy(1)<x>,<y>R/Wthe CIE color point of light <n>, e.g. "0.4575,0.4099". This is the API's native color format
light.<n>.temperature(2)153 ... 500R/Wthe white color temperature of light <n>, in mirek (reciprocal megakelvin)
light.<n>.powerup(3)powerfailR/Wafter a power loss light <n> returns to its previous state, staying off if it was off
last_on_stateR/Wthe same, but it comes back on if it was off
safetyR/Wit comes on at full brightness in warm white
light.<n>.colorloop(1)1Wstart a color changing effect on light <n>. See Color loop
0Wstop the effect on light <n>
light.<n>.blinksingleWperform a single blink on light <n>
longWblink light <n> for about 15 seconds
0Wstop blinking light <n>
light.<n>.name<text>Rthe name of light <n> as configured in the Hue app
light.<n>.uuid<uuid>Rthe CLIP v2 identifier of light <n>

Note 1​

Only available on lights with color capabilities. The driver detects this from the light itself, not from a model list.

Note 2​

Only available on lights with tunable white capabilities. The supported range varies per model, and the bridge moves to the closest value it can produce.

Note 3​

Only available on lights that support configurable power-on behaviour. See Power-on behaviour.

Datapoints — motion sensors​

Each Hue motion sensor is a single device that provides motion detection, an ambient light level, a temperature reading and a battery level. All of them are published under a single sensor.<n> prefix.

IDValueR/WDescription
sensor.<n>.motion1Rmotion detected
0Rno motion detected
sensor.<n>.enabled1R/Wmotion detection is enabled / enable it
0R/Wmotion detection is disabled / disable it
sensor.<n>.illuminance0 ... nRambient light level in lux
sensor.<n>.lightlevel0 ... nRambient light level in the bridge's raw logarithmic scale, 10000*log10(lux)+1
sensor.<n>.temperature<n.n>Rtemperature in degrees Celsius, with one decimal
sensor.<n>.battery0 ... 100Rbattery charge, in percent
sensor.<n>.batterystatenormalRbattery level is sufficient
lowRbattery level low, replace the battery soon
criticalRbattery level critical, the device can fail at any moment
sensor.<n>.reachable1 / 0Rthe sensor is connected to the bridge
sensor.<n>.update<text>Rfirmware state. See Firmware updates
sensor.<n>.name, .uuid<text>R

The motion datapoint is not published until the sensor has reported at least once, so a rule triggering on it will not fire on a stale value at start-up.

Datapoints — switches and dials​

Hue Dimmer Switches, Tap Dials, Smart Buttons and Wall Switch Modules are published under switch.<n>, one prefix per physical device. Each control on the device has its own datapoint, numbered by the control identifier the device reports — for a Dimmer Switch that is the number printed next to each key. How a press is published is explained in How button events are published.

IDValueR/WDescription
switch.<n>.button<c>initial_pressRkey <c> was pressed
repeatRkey <c> is being held
short_releaseRkey <c> was released after a short press
long_releaseRkey <c> was released after a long press
double_short_releaseRkey <c> was double-pressed
long_pressRkey <c> has been held long enough to count as a long press
switch.<n>.button<c>.cnt0 ... nRnumber of events received from key <c> since HSYCO started
switch.<n>.bell<c>as aboveRsame, for a doorbell button
switch.<n>.bell<c>.cnt0 ... nR
switch.<n>.dialclock_wiseRthe dial was turned clockwise
counter_clock_wiseRthe dial was turned anticlockwise
switch.<n>.dial.cnt0 ... nRnumber of rotation events received
switch.<n>.dial.steps0 ... 32767Ramount of rotation in the last event, 1000 steps per full turn
switch.<n>.dial.duration0 ... 65534Rduration of the last rotation, in milliseconds
switch.<n>.dial.actionstart / repeatRwhether the last event began a rotation or continued one
switch.<n>.battery0 ... 100Rbattery charge, in percent
switch.<n>.batterystatenormal / low / criticalR
switch.<n>.reachable1 / 0R
switch.<n>.update<text>Rfirmware state. See Firmware updates
switch.<n>.name, .uuid<text>R

How button events are published​

A key press is a moment, not a state, so each control publishes two datapoints.

The base datapoint holds the last event received, and is written on every event even when the value has not changed. So pressing the same key twice in a row reports short_release twice, and a rule watching for short_release fires both times. Between presses the datapoint keeps the last event, which makes it meaningful to read at any moment rather than resting empty.

The .cnt datapoint is a counter that increases by one on every event from that key. Use it when what matters is that something happened rather than which event it was, or to detect a burst of events without inspecting each one.

Counters start at zero when HSYCO starts and are not persisted.

Each control is numbered by the identifier the device itself reports — the number printed next to each key on a Dimmer Switch. A device with a single control, such as a Smart Button, publishes just that one, and its number is not necessarily zero.

The datapoints are written only when a key is actually pressed. The periodic resynchronization re-reads the state of everything, including the last press each key reported, but never republishes it: a press is reported once, when it happens.

Datapoints — rooms and zones​

Rooms and zones are published under group.<n>. Controlling a group sends one command to the bridge instead of one per light, which is also the only way to dim a whole room without visible stagger.

IDValueR/WDescription
group.<n>.on1 / 0R/Wany light in the group is on / turn the group on or off
flipWinvert the state of the group
group.<n>.dimmeroff, 1% ... 100%R/Waverage brightness of the lights that are on
onWturn the group on at its previous brightness
group.<n>.brightness1 ... 254R/W
group.<n>.motion1 / 0Raggregated motion of the sensors in the group
group.<n>.lightlevel0 ... nRaggregated light level, raw scale
group.<n>.illuminance0 ... nRaggregated light level, in lux
group.<n>.typeroom / zoneR
group.<n>.name, .uuid<text>R
note

Philips limits grouped commands to one per second, against ten per second for an individual light. The driver enforces this: rapid changes to a group are merged and sent at that rate. A slider bound to a group datapoint will therefore follow more coarsely than one bound to a single light.

Datapoints — scenes​

IDValueR/WDescription
scene.<n>.recall1 or activeWactivate the scene
dynamic_paletteWactivate the scene in dynamic mode, cycling through its colours
staticWactivate the scene without any dynamic behaviour
scene.<n>.name<text>R
scene.<n>.group<text>Rthe room or zone the scene belongs to
scene.<n>.uuid<uuid>R

A bridge typically holds a large number of scenes. Use resources to leave them out if you do not need them.

Datapoints — Hue Secure​

Contact sensors, cameras and sirens. Each device is published under the prefix matching what it is, and a device that combines functions — a camera with a built-in siren — publishes all of them under its own single prefix.

IDValueR/WDescription
contact.<n>.contact1Rthe contact is closed
0Rthe contact is open
contact.<n>.tamper1 / 0Rthe device reports tampering
contact.<n>.enabled1 / 0R/W
camera.<n>.motion1 / 0Rmotion detected by the camera
camera.<n>.enabled1 / 0R/W
speaker.<n>.alarm<sound>R/Wsound the alarm. See Sounds
speaker.<n>.chime<sound>R/Wplay a chime
speaker.<n>.alert<sound>Wplay an alert
speaker.<n>.mute1 / 0R/Wmute the device. The siren is not affected by mute
speaker.<n>.alarm.sounds<list>Rthe sounds this device accepts for alarm, comma separated
speaker.<n>.chime.sounds<list>Rthe sounds it accepts for chime

All Secure devices also publish .battery, .batterystate, .reachable, .update, .name and .uuid, and any of them that reports tampering publishes .tamper as shown above for contact sensors. Mains-powered and Wi-Fi devices report reachable from their Wi-Fi connection rather than from Zigbee.

Sounds​

The sound datapoints take <sound>, <sound>;<volume> or, for alarm only, <sound>;<volume>;<seconds>. Volume is 0 to 100. Writing off, 0 or no_sound stops the sound.

IO hue.speaker.1.alarm = siren;100;30
IO hue.speaker.1.chime = ding_dong_classic;40
IO hue.speaker.1.alarm = off

Sounding a Hue Smart Chime is therefore:

IO hue.speaker.1.chime = ding_dong_classic

Devices differ in which sounds they have, and each feature has its own set — a chime sound is generally not available to the alarm, and the other way round. Rather than guessing, read the .sounds datapoints, which list exactly what the device in front of you accepts:

speaker.1.chime.sounds no_sound,ding_dong_classic,westminster_modern
speaker.1.alarm.sounds no_sound,siren,alert

Writing a sound the device does not have is refused before it reaches the bridge, and the message says what it does have:

Error executing command speaker.1.chime=siren - this device does not have the sound 'siren' for chime, it accepts: no_sound,ding_dong_classic,westminster_modern

Across the whole product range the sounds are alert, bleep, ding_dong_classic, ding_dong_modern, ding_dong_xylo, rise, siren, westminster_classic, westminster_modern, hue_default, sonar, swing, bright, bright_modern, glow, bounce, reveal, welcome, fairy, galaxy, echo and no_sound.

Firmware updates​

Every device publishes an update datapoint reporting the state of its firmware: no_update, update_pending, ready_to_install or installing. Updates are managed by the bridge and the Hue app; HSYCO reports the state but does not trigger them.

Touchlink claims the nearest Zigbee light and adds it to this bridge, including a light that is currently joined to a different hub. It is the practical way to take over a light when the hub that currently owns it is unavailable, has been replaced, or is not a Hue bridge — no access to the old hub is needed, only physical proximity.

Write 1 to the touchlink datapoint to start a scan:

IO hue.touchlink = 1

The touchlink datapoint reads 1 while the scan is running and returns to 0 when it finishes. A light claimed by the scan appears as new light.<n> datapoints without a restart.

Preparation​

The scan claims whichever light has the strongest signal, so it must be the one you intend:

  • place the light within about a metre of the bridge, and closer to it than any other light,
  • switch off, or move well away, every other light that could respond,
  • make sure the light is powered on.

Claiming a light that belongs to a neighbouring installation is a real possibility if these precautions are ignored. For the same reason the driver only starts a scan on an explicit 1, refuses to run two scans at once, and never starts one by itself.

Lights only​

Touchlink is part of the Zigbee Light Link profile, in which lights are the devices that can be claimed. It applies to bulbs, lightstrips and light-like devices such as Zigbee smart plugs, including third-party ones.

It does not work for motion sensors or switches. Those are battery-powered devices that do not listen for a Touchlink scan — a Hue Dimmer Switch is in fact a Touchlink initiator itself, which is what the "hold the dimmer next to the bulb" reset relies on. To move a sensor or a switch to this bridge, reset it with the setup button in its battery compartment and then add it from the Hue app.

caution

Touchlink is only available through the CLIP v1 API, which this driver otherwise does not use.

There is no Touchlink in the Hue API v2, and Philips did not replace it: the word does not appear anywhere in the v2 documentation. Philips has stated that the v1 API will eventually be withdrawn, and when that happens on a given bridge firmware this command will stop working. It then reports:

Touchlink failed - the bridge no longer implements the CLIP v1 API (HTTP 404) - Touchlink is not available on the v2 API and cannot be used on this bridge

Every other feature of this driver uses the v2 API only and is unaffected.

The v2 alternative​

If you do have access to the hub that currently owns the light, releasing it there is the supported route and does not depend on the v1 API. On a Hue bridge, deleting the device sends it a Zigbee leave command and it becomes available to be added elsewhere — but only if it is powered on and in range at that moment, otherwise the hub forgets it while the light stays bound and only a physical reset or Touchlink will recover it.

Power-on behaviour​

A Hue light that loses power — a breaker, a wall switch, an unplugged lamp — comes back on at full brightness by default, and stays on. Modern lights can be told to do something else instead, and they remember it themselves: the setting lives in the lamp, so it is applied the moment power returns, with no involvement from the bridge or from HSYCO.

Set the powerup option to apply a behaviour to every capable light:

ValueHue app nameAfter power returns, the light…
powerfailPower loss recoveryreturns to the colour and brightness it had when power was lost, and if it was off it stays off
last_on_state—returns to the same settings, but if it was off it comes back on, in its last on state
safetyDefaultcomes on at full brightness in warm white (2700 K), whatever it was doing before

powerfail is the one to use if the intent is that the lights stay as HSYCO left them: a light that HSYCO switched off stays off, and one that was on returns exactly as it was. The difference from last_on_state is only in that first case, and it is the difference between a room staying dark after a power cut and every lamp in it coming on.

A single light can also be set individually through its light.<n>.powerup datapoint, which reports the current setting and accepts a new one.

Which lights support it​

The driver does not guess from model names. A light that supports the feature says so in its own description, and the datapoint is published only for those.

Because the setting is stored inside the lamp, the driver writes it only when it differs from what the lamp already has, and only once per light per run. It is a configuration value, not something to be enforced continuously — changing it later from the Hue app is respected, not overwritten.

At start-up, any light that cannot do this is named in the log:

These lights do not support the powerup feature and will not restore their state after a power loss: 4 (Garden spot), 7 (Old bedside lamp)

Those lights will still come on by themselves after a power loss. There is no way to change that from outside the lamp; the usual remedies are a firmware update from the Hue app, if one is available for that model, or replacing it.

note

This replaces the master option of the previous version of this driver, which polled the lights and pushed HSYCO's saved state back onto any that had changed. Letting the lamp hold the setting is both more reliable and less intrusive: it works even while HSYCO is stopped, it acts the instant power returns rather than at the next poll, and it never overrides a change made deliberately somewhere else.

Color​

The rgb and xy datapoints hold their components separated by commas:

light.1.rgb 255,67,31
light.1.xy 0.6655,0.3173

Writing accepts a comma, a semicolon, an asterisk or spaces, so all of these set the same colour:

IO hue.light.1.rgb = 255,67,31
IO hue.light.1.rgb = 255;67;31
IO hue.light.1.rgb = 255*67*31
IO hue.light.1.rgb = 255 67 31
note

The HUE I/O Server of HSYCO 4.1 published these datapoints separated by semicolons. A project that reads light.<n>.rgb as text, rather than binding it to a colorpicker or another user interface object, has to be updated. User interface objects are not affected.

The CLIP v2 API represents color only as a CIE xy point plus a separate brightness, and has no hue or saturation values at all. The hue, saturation and rgb datapoints are computed by the driver, clamped to the color range the specific bulb can physically produce.

This has one consequence worth knowing. A color the bulb can produce reads back as it was written. A color outside its range, as fully saturated colors often are, is moved to the closest one the bulb can produce, and rgb reports that color, which is what the light is actually showing: 255,0,0 reads back as about 255,39,0 on a recent bulb, and as about 255,67,0 on an older one. The hue and saturation datapoints are the exception: when HSYCO sets a color, they read back exactly as written. When the color is changed from somewhere else — the Hue app, a wall dimmer, a scene — they are derived from the bulb's actual color point, and a fully saturated color that the bulb cannot reproduce reads back slightly less saturated than requested.

Use the xy datapoint when you need the exact value the bridge holds, with no conversion.

Reachability​

light.<n>.reachable, and the same datapoint on sensors, switches and Secure devices, report whether the bridge can reach that device over Zigbee or Wi-Fi.

While the connection datapoint is offline the bridge itself cannot be reached, and nothing behind it can be either, so every device reports reachable as 0 and every user interface device carries the fault flag, whatever the bridge last said about them. What the bridge reported is not lost: when the connection comes back, each device returns to its own reachability immediately, without waiting for the next resynchronization.

Color and state​

The rgb, hue, saturation and xy datapoints report the color of a light whether it is on or off. The bridge keeps the color of a light that is off, so this is the color it comes back to, and a colorpicker shows it instead of showing black.

Color and state are independent. Setting a color does not turn a light on, and the state moves only when it is written: with on, off or flip, on the on datapoint or on rgb itself, or by adding on or off as a last field to a color, which sets both in one write.

IO hue.light.1.rgb = 255,67,31 # set the color, on or off as it was
IO hue.light.1.rgb = 255,67,31,on # set the color and turn the light on
IO hue.light.1.on = 1 # turn it on, at the color it was given

A color of all zeros is not a color and is ignored: a light is turned off with off, 0, or its on datapoint. A status field is always the word on or off, never 1 or 0, so that it can never be read as one of the three components.

note

In the catalog, and therefore in the User Interface, a light is published as <r>*<g>*<b>*<on|off>, and an unreachable light carries fault as a further field, <r>*<g>*<b>*<on|off>*fault, so that the interface raises its fault flag while still showing the light as it is. This is the format the colorpicker object reads. The dimmer datapoint of a light or a group is published in the same way, as off or <n>%, with *fault appended.

Color loop​

The color loop effect of the CLIP v1 API was removed by Philips and has no equivalent in the CLIP v2 API. With the default colorloopmode=effect, writing 1 to the colorloop datapoint starts the closest color changing effect the light supports, chosen from the effects the light itself advertises. Writing 0 stops it.

The effect is not identical to the old color loop, and lights that support no suitable effect log a message and ignore the command.

User Interface​

To control a Hue light as a dimmer, i.e. to change its brightness without changing color, add a slider or a button object to your project page and set its address field to the corresponding dimmer datapoint. The same applies to a room or zone, using its group.<n>.dimmer datapoint.

To control a color light using its RGB channels use a colorpicker object and set its address to the corresponding rgb datapoint.

Release Notes​

4.2.0​

  • the driver has been rewritten on the Philips Hue CLIP v2 API, replacing the discontinued Philips Java SDK. Existing installations are upgraded in place: the bridge does not have to be paired again, and lights keep their numbering — see Upgrading from HSYCO 4.1
  • added support for the Hue Bridge Pro
  • support for the first generation Hue bridge (v1, round) has been removed, as it does not implement the CLIP v2 API and cannot be updated to a firmware that does
  • state is now received as push events over the bridge's event stream instead of being polled, so changes are reported in about a second instead of at the polling interval
  • added support for rooms and zones, scenes, Hue Dimmer Switches, Tap Dials and Smart Buttons, and Hue Secure contact sensors, cameras and sirens
  • added the resources option, to select which families of devices are exposed
  • added the ipaddress option and extended the mac option, which now also locates a bridge whose address is assigned by DHCP and follows it when the address changes
  • added the discovery option: the driver operates entirely on the local network by default, and only queries the Philips cloud discovery service if explicitly configured to
  • added the idmode and colorloopmode options
  • the pollinterval option is now the interval of a background safety resynchronization, and its default has changed from 10 to 300 seconds
  • replaced the master option with the new powerup option and light.<n>.powerup datapoint, which configure the lamp's own power-on behaviour so that a light restores its state after a power loss by itself, instead of being polled and corrected. Lights that do not support the feature are listed in the log at start-up — see Power-on behaviour
  • a newly configured I/O Server with no ipaddress or mac now selects the bridge that no other I/O Server has paired with, instead of the first one to answer, so a second bridge can be added without configuring anything; when the choice is ambiguous the driver reports which bridges it found and which I/O Server owns each — see Adding a second bridge
  • persistent state, including the bridge application key and the resource numbering, is now kept in the bridge.ini file of each I/O Server instead of persistent variables — see The bridge.ini file
  • the connection to the bridge is now HTTPS only, with full certificate validation against the Philips Hue root certificate authorities
  • the rgb, hue, saturation and xy datapoints now report the color of a light that is off, instead of reporting black, so the user interface can show the color the light will come back to. A light is published to the user interface as <r>*<g>*<b>*<on|off>, with *fault appended while it is unreachable — see Color and state
  • while the connection to the bridge is offline, every device now reports reachable as 0 and carries the fault flag in the user interface, returning to its own state as soon as the bridge answers again — see Reachability
  • BREAKING CHANGE. Writing a color to the rgb datapoint no longer turns the light on, and writing 0,0,0 no longer turns it off: color and state are now independent, as they already are for the hue, saturation and xy datapoints. EVENTS and user code that relied on a color write to switch a light must add the state explicitly, as IO hue.light.1.rgb = 255,67,31,on, or write the on datapoint. Both forms of the write also accept on, off and flip

3.7.0​

  • added support for Hue White devices

3.6.0​

  • added support for Philips Hue bridge 2.0 (Java Hue SDK 1.8.1 API)

3.5.0​

  • initial release

Philips is a registered trademark of Koninklijke Philips N.V., used under licence. Hue and Philips Hue are trademarks of Signify Holding B.V.