Class AdaptiveLightingController

This class allows adding Adaptive Lighting support to Lightbulb services. The Lightbulb service MUST have the Characteristic.ColorTemperature characteristic AND the Characteristic.Brightness characteristic added. The light may also expose Characteristic.Hue and Characteristic.Saturation characteristics (though additional work is required to keep them in sync with the color temperature characteristic. see below)

How Adaptive Lighting works: When enabling AdaptiveLighting the iDevice will send a transition schedule for the next 24 hours. This schedule will be renewed all 24 hours by a HomeHub in your home (updating the schedule according to your current day/night situation). Once enabled the lightbulb will execute the provided transitions. The color temperature value set is always dependent on the current brightness value. Meaning brighter light will be colder and darker light will be warmer. HomeKit considers Adaptive Lighting to be disabled as soon a write happens to either the Hue/Saturation or the ColorTemperature characteristics. The AdaptiveLighting state must persist across reboots.

The AdaptiveLightingController can be operated in two modes: AdaptiveLightingControllerMode.AUTOMATIC and AdaptiveLightingControllerMode.MANUAL with AUTOMATIC being the default. The goal would be that the color transition is done DIRECTLY on the light itself, thus not creating any additional/heavy traffic on the network. So if your light hardware/API supports transitions please go the extra mile and use MANUAL mode.

Below is an overview what you need to or consider when enabling AdaptiveLighting (categorized by mode). The AdaptiveLightingControllerMode can be defined with the second constructor argument.

AUTOMATIC (Default mode):

This is the easiest mode to setup and needs less to no work form your side for AdaptiveLighting to work. The AdaptiveLightingController will go through setup procedure with HomeKit and automatically update the color temperature characteristic base on the current transition schedule. It is also adjusting the color temperature when a write to the brightness characteristic happens. Additionally, it will also handle turning off AdaptiveLighting, when it detects a write happening to the ColorTemperature, Hue or Saturation characteristic (though it can only detect writes coming from HomeKit and can't detect changes done to the physical devices directly! See below).

So what do you need to consider in automatic mode:

  • Brightness and ColorTemperature characteristics MUST be set up. Hue and Saturation may be added for color support.
  • Color temperature will be updated all 60 seconds by calling the SET handler of the ColorTemperature characteristic. So every transition behaves like a regular write to the ColorTemperature characteristic.
  • Every transition step is dependent on the current brightness value. Try to keep the internal cache updated as the controller won't call the GET handler every 60 seconds. (The cached brightness value is updated on SET/GET operations or by manually calling Characteristic.updateValue on the brightness characteristic).
  • Detecting changes on the lightbulb side: Any manual change to ColorTemperature or Hue/Saturation is considered as a signal to turn AdaptiveLighting off. In order to notify the AdaptiveLightingController of such an event happening OUTSIDE of HomeKit you must call disableAdaptiveLighting manually!
  • Be aware that even when the light is turned off the transition will continue to call the SET handler of the ColorTemperature characteristic.
  • When using Hue/Saturation: When using Hue/Saturation in combination with the ColorTemperature characteristic you need to update the respective other in a particular way depending on if being in "color mode" or "color temperature mode". When a write happens to Hue/Saturation characteristic in is advised to set the internal value of the ColorTemperature to the minimal (NOT RAISING an event). When a write happens to the ColorTemperature characteristic just MUST convert to a proper representation in hue and saturation values, with RAISING an event. As noted above you MUST NOT call the Characteristic.setValue method for this, as this will be considered a write to the characteristic and will turn off AdaptiveLighting. Instead, you should use Characteristic.updateValue for this. You can and SHOULD use the supplied utility method ColorUtils.colorTemperatureToHueAndSaturation for converting mired to hue and saturation values.

MANUAL mode:

Manual mode is recommended for any accessories which support transitions natively on the devices end. Like for example ZigBee lights which support sending transitions directly to the lightbulb which then get executed ON the lightbulb itself reducing unnecessary network traffic. Here is a quick overview what you have to consider to successfully implement AdaptiveLighting support. The AdaptiveLightingController will also in manual mode do all the setup procedure. It will also save the transition schedule to disk to keep AdaptiveLighting enabled across reboots. The "only" thing you have to do yourself is handling the actual transitions, check that event notifications are only sent in the defined interval threshold, adjust the color temperature when brightness is changed and signal that Adaptive Lighting should be disabled if ColorTemperature, Hue or Saturation is changed manually.

First step is to setup up an event handler for the AdaptiveLightingControllerEvents.UPDATE, which is called when AdaptiveLighting is enabled, the HomeHub updates the schedule for the next 24 hours or AdaptiveLighting is restored from disk on startup. In the event handler you can get the current schedule via AdaptiveLightingController.getAdaptiveLightingTransitionCurve, retrieve current intervals like AdaptiveLightingController.getAdaptiveLightingUpdateInterval or AdaptiveLightingController.getAdaptiveLightingNotifyIntervalThreshold and get the date in epoch millis when the current transition curve started using AdaptiveLightingController.getAdaptiveLightingStartTimeOfTransition. Additionally AdaptiveLightingController.getAdaptiveLightingBrightnessMultiplierRange can be used to get the valid range for the brightness value to calculate the brightness adjustment factor. The method AdaptiveLightingController.isAdaptiveLightingActive can be used to check if AdaptiveLighting is enabled. Besides, actually running the transition (see AdaptiveLightingTransitionCurveEntry) you must correctly update the color temperature when the brightness of the lightbulb changes (see AdaptiveLightingTransitionCurveEntry.brightnessAdjustmentFactor), and signal when AdaptiveLighting got disabled by calling AdaptiveLightingController.disableAdaptiveLighting when ColorTemperature, Hue or Saturation where changed manually. Lastly you should set up a event handler for the AdaptiveLightingControllerEvents.DISABLED event. In yet unknown circumstances HomeKit may also send a dedicated disable command via the control point characteristic. Be prepared to handle that.

Hierarchy

  • EventEmitter
    • AdaptiveLightingController

Implements

Constructors

Methods

  • Returns the minimum interval threshold (in milliseconds) a accessory may notify HomeKit controllers about a new color temperature value via event notifications (what happens when you call Characteristic.updateValue). Meaning the accessory should only send event notifications to subscribed HomeKit controllers at the specified interval.

    Typically this evaluates to 600000 milliseconds (10 minutes).

    Returns number

  • It is not necessarily given, that we have the same time (or rather the correct time) as the HomeKit controller who set up the transition schedule. Thus we record the delta between our current time and the the time send with the setup request. timeOffset is defined as Date.now() - getAdaptiveLightingStartTimeOfTransition();. So in the case were we actually have a correct local time, it most likely will be positive (due to network latency). But of course it can also be negative.

    Returns number

  • This method returns the interval (in milliseconds) in which the light should update its internal color temperature (aka changes it physical color). A lightbulb should ideally change this also when turned of in oder to have a smooth transition when turning the light on.

    Typically this evaluates to 60000 milliseconds (60 seconds).

    Returns number