Hue Emulator

A framework for emulating Hue smart light devices via the Hue::Bridge class.

A real bridge talks to Hue devices via ZigBee, however with Sming you can control anything you want using the published API. Refer to specifications available at https://developers.meethue.com (free account login required).

Setup

Refer to the Basic Alexa sample for details of how to use this library. Here are a few key notes.

A HttpServer object is required to allow the framework to respond to requests. Note that Gen 3+ Hue Bridges listen on port 80 (standard HTTP), however older versions use port 1901. This library has only been tested on port 80.

In your application, remember to add bodyparsers for JSON and XML:

server.setBodyParser(MIME_JSON, bodyToStringParser);
server.setBodyParser(MIME_XML, bodyToStringParser);

Without these, you’ll get empty bodies for incoming requests.

The sample demonstrates use of provided On/Off, Dimmable and Colour device types with a global callback function.

Ideally you should provide your own custom Hue devices by inheriting from Hue::Device. This is demonstrated using MyHueDevice. The device ID is 666.

API

class Hue::Bridge : public UPnP::schemas_upnp_org::device::Basic1Template<Bridge>

Public Types

using ConfigDelegate = Delegate<void(const Config &config)>

Called when a new user key is created.

The application should use this to store new users in persistent memory. At startup, these should be passed back via the configure() method.

using StateChangeDelegate = Delegate<void(const Hue::Device &device, Hue::Device::Attributes attr)>

A global callback may be provided to perform actions when device states change.

The callback is invoked only when all request actions have been completed. The current state may be quereied using device::getAttribute.

Parameters
  • device – The device which has been updated

  • attr – A set of flags indicating which attributes were changed

Public Functions

inline Bridge(Hue::Device::Enumerator &devices)

Constructor.

Parameters

devices – List of devices to present

void configure(const Config &config)

Perform a configuration action.

Parameters

config – The action to perform

inline void enablePairing(bool enable)

Enable creation of new users.

This could be enabled via web page on local Access Point, or physical push-button. It should also be time limited, so exits pairing mode after maybe 30 seconds. If a user creation request is received then this is disabled automatically.

Note

DO NOT leave this permanently enabled!

inline const Stats &getStats()

Get bridge statistics.

Returns

const – Stats&

inline void resetStats()

Clear the bridge statistics.

inline const UserMap &getUsers() const

Access the list of users.

Returns

const – UserMap&

void getStatusInfo(JsonObject json)

Get bridge status information in JSON format.

Parameters

json – Where to write information

inline void deviceStateChanged(const Hue::Device &device, Hue::Device::Attributes changed)

Devices call this method when their state has been updated.

Note

Applications should not call this method

struct Config

Public Members

Type type

Configuration action to perform.

String deviceType

How device identifies itself.

String name

Randomly generated key.

class Hue::Device : public UPnP::Item

Subclassed by Hue::OnOffDevice

Public Types

using Callback = Delegate<void(Status status, int errorCode)>

Callback invoked when setAttribute() has completed.

Note

Any status other than success is considered a failure

Parameters
  • status – Result of the operation

  • errorCode – Application-specific error code

Public Functions

virtual Status setAttribute(Attribute attr, unsigned value, Callback callback) = 0

Set a device attribute.

Note

DO NOT invoke the callback directly: only use it if pended.

Parameters
  • attr – The attribute to change

  • value – Value for the attribute (exact type is attribute-specific)

  • callback – If you return Status::pending, invoke this callback when completed

Returns

Status

virtual bool getAttribute(Attribute attr, unsigned &value) const = 0

Get the (cached) device attribute value.

Parameters
  • attr

  • value

Returns

bool – true on success, false if attribute not supported or value unknown

virtual String getUniqueId() const

Returns the unique device ID string.

Note

Other forms of ID string may be used, however for maximum compatibility the standard format should be used. By default, this method uses the WiFi station MAC address, with 00:11 appended plus the 8-bit device ID.

Returns

String – Unique ID of the form AA:BB:CC:DD:EE:FF:00:11-XX, consisting of a 64-bit Zigbee MAC address plus unique endpoint ID.

inline bool operator==(const Device &dev) const

Two devices are considered equal if they have the same ID.

class Enumerator : public UPnP::Enumerator<Device, Enumerator>

Abstract class to manage a list of devices.

Note

Applications must provide an implementation of this for the bridge. Returned device objects may only be considered valid for the duration of the current task call as they may be destroyed at any time.

Subclassed by Hue::DeviceListEnumerator

Public Functions

virtual Device *find(Device::ID id)

Lookup device by ID.

Note

With default implementation, enumerator position is updated

Returns

Device* – nullptr if not found

virtual Device *find(const String &name)

Lookup device by name.

Note

With default implementation, enumerator position is updated

Returns

Device* – nullptr if not found

class OnOffDevice : public Hue::Device

Subclassed by Hue::DimmableDevice

class DimmableDevice : public Hue::OnOffDevice

Subclassed by Hue::ColourDevice

class ColourDevice : public Hue::DimmableDevice
enum Hue::Status

Status of a setAttribute request.

Values:

enumerator success

The action was performed immediately without error.

enumerator pending

The action was accepted but requires further processing.

Use this to perform requests asynchronously. You MUST invoked the provided Callback function to complete the request.

When controlling remote devices, for example connected via serial link, you might issue the command immediately and then return pending. When the serial response is received, or a timeout occurs, then the request can be completed. Note that the error code passed to the callback is optional and will be specific to your application: it will be output in verbose debug mode so may be useful.

enumerator error

Action could not be completed.

If the Attribute not supported by your device, or an internal I/O error occurred then return this value.

References

Used by

SoC support

  • esp32

  • esp32c3

  • esp32s2

  • esp32s3

  • esp8266

  • host

  • rp2040