Light xyL Server

The Light xyL Server represents a single light on a mesh device. This model is well suited for implementation in light sources with multi-color light emission. It should be instantiated in the light fixture node.

Three states can be used to configure the lighting output of an element:

  • Lightness - This state determines the lightness of a tunable white light emitted by an element.

  • x - Determines the x coordinate on the CIE1931 color space chart of a color light emitted by an element.

  • y - Determines the y coordinate on the CIE1931 color space chart of a color light emitted by an element.

These model instances share the states of the Light xyL Server, but accept different messages. This allows for a fine-grained control of the access rights for the Light xyL states, as the model instances can be bound to different application keys. The following two model instances are added:

  • Light xyL Server - Provides write access to the Lightness, x and y states for the user, in addition to read access to all meta states

  • Light xyL Setup Server - Provides write access to Default xyL state and Range meta states, allowing configurator devices to set up a range for the x and y state, and a default xyL state

The extended Light Lightness Server model should be defined and initialized separately, and the pointer to this model should be passed to the Light xyL Server initialization macro.

Model composition

The extended Light Lightness Server shall be instantiated on the same element:

Element N

Light Lightness Server

Light xyL Server

The Light xyL Server structure does not contain a Light Lightness Server instance, so this must be instantiated separately.

In the application code, this would look like this:

static struct bt_mesh_lightness_srv lightess_srv = BT_MESH_LIGHTNESS_SRV_INIT(&lightness_cb);

static struct bt_mesh_light_xyl_srv xyl_srv =
     BT_MESH_LIGHT_XYL_SRV_INIT(&lightness_srv, &xyl_handlers);

static struct bt_mesh_elem elements[] = {
     BT_MESH_ELEM(
             1, BT_MESH_MODEL_LIST(
                BT_MESH_MODEL_LIGHTNESS_SRV(&lightness_srv),
                BT_MESH_MODEL_LIGHT_XYL_SRV(&xyl_srv)),
             BT_MESH_MODEL_NONE),
};

Usage with the Light HSL Server

Just like the Light xyL Server, the Light HSL Server provides the ability to control colored lights. In some cases, it may be desirable to use the Light HSL and Light xyL Servers to provide two different interfaces for controlling the same light. To achieve this, the Light xyL and Light HSL Server models should be instantiated on the same element, and share the same Light Lightness Server.

With the Light HSL Server’s corresponding Light Hue Server and Light Saturation Server models, the composition data should look like this:

Element N

Element N+1

Element N+2

Light Lightness Server

Light Hue Server

Light Saturation Server

Light HSL Server

Light xyL Server

In the application code, this would look like this:

static struct bt_mesh_lightness_srv lightess_srv =
   BT_MESH_LIGHTNESS_SRV_INIT(&lightness_cb);

static struct bt_mesh_light_hsl_srv hsl_srv =
     BT_MESH_LIGHT_HSL_SRV_INIT(&lightness_srv, &hue_cb, &sat_cb);

static struct bt_mesh_light_xyl_srv xyl_srv =
     BT_MESH_LIGHT_XYL_SRV_INIT(&lightness_srv, &xyl_handlers);

static struct bt_mesh_elem elements[] = {
     BT_MESH_ELEM(
             1, BT_MESH_MODEL_LIST(
         BT_MESH_MODEL_LIGHTNESS_SRV(&lightness_srv),
         BT_MESH_MODEL_LIGHT_HSL_SRV(&hsl_srv),
         BT_MESH_MODEL_LIGHT_XYL_SRV(&xyl_srv)),
             BT_MESH_MODEL_NONE),
     BT_MESH_ELEM(
             2, BT_MESH_MODEL_LIST(BT_MESH_MODEL_LIGHT_HUE_SRV(&hsl_srv.hue)),
             BT_MESH_MODEL_NONE),
     BT_MESH_ELEM(
             3, BT_MESH_MODEL_LIST(BT_MESH_MODEL_LIGHT_SAT_SRV(&hsl_srv.sat)),
             BT_MESH_MODEL_NONE),
};

While there is just one shared instance of the Light Lightness Server controlling the Lightness in this configuration, the light’s hue and saturation level may be controlled independently by the Light xyL and Light HSL Servers. The binding between the Light xyL Server’s x and y states, and the Light HSL Server’s Hue and Saturation states is application-specific.

Even though there are no qualification tests verifying the binding between the color spectrum states of the Light xyL and Light HSL Servers, application developers are strongly encouraged to implement the general characteristics of bound states:

  • Any changes to one state should be immediately reflected in the other.

  • If publication is enabled for any of the models, a change to the bound state of one of the models should be published on both.

  • Any range limitations on one of the bound states should be respected when setting the value of the other bound state.

States

The xyL model contains the following states:

Lightness: uint16_t

The Lightness state represents the emitted light level of an element, and ranges from 0 to 65535. The Lightness state is shared by the extended Light Lightness Server model.

The Lightness state power-up behavior is determined by the On Power Up state of the extended Generic Power OnOff Server:

The Lightness state is held and managed by the extended Light Lightness Server.

x: uint16_t

The x state represents the x coordinate on the CIE1931 color space chart of a color light emitted by an element. This is a 16-bit unsigned integer representation of a scale from 0 to 1 using the formula:

CIE1931_x = (Light xyL x) / 65535

The x state power-up behavior is determined by the On Power Up state of the extended Generic Power OnOff Server:

Your application is expected to hold the state memory and provide access to the state through the bt_mesh_light_xyl_srv_handlers handler structure.

y: uint16_t

The y state represents the y coordinate on the CIE1931 color space chart of a color light emitted by an element. This is a 16-bit unsigned integer representation of a scale from 0 to 1 using the formula:

CIE1931_y = (Light xyL y) / 65535

The y state power-up behavior is determined by the On Power Up state of the extended Generic Power OnOff Server:

Your application is expected to hold the state memory and provide access to the state through the bt_mesh_light_xyl_srv_handlers handler structure.

Default xy: bt_mesh_light_xy

The Default xy state is a meta state that controls the default x and y level. It is used when the light is turned on, but its exact state levels are not specified.

The memory for the Default xy state is held by the model, and the application may receive updates on state changes through the bt_mesh_light_xyl_srv_handlers.default_update callback.

Range: bt_mesh_light_xyl_range

The Range state is a meta state that determines the accepted x and y level range. If the x or y level is set to a value outside the currently defined Range state value, it is moved to fit inside the range. If the Range state changes to exclude the current x or y level, the level should be changed accordingly.

The memory for the Range state is held by the model, and the application may receive updates on state changes through the bt_mesh_light_xyl_srv_handlers.range_update callback.

Extended models

The Light xyL Server extends the following model:

State of the extended Light Lightness Server model is partially controlled by the Light xyL Server, making it able to alter states like Lightness and Default Lightness of the Light Lightness Server model.

Persistent storage

The Light xyL Server stores the following information:

  • Any changes to states Default xyL and Range

  • The last known Lightness, x, and y levels

In addition, the model takes over the persistent storage responsibility of the Light Lightness Server model.

This information is used to reestablish the correct light configuration when the device powers up.

If CONFIG_BT_SETTINGS is enabled, the Light xyL Server stores all its states persistently using a configurable storage delay to stagger storing. See CONFIG_BT_MESH_STORE_TIMEOUT.

The Light xyL Server can use the emergency data storage (EMDS) together with persistent storage to:

  • Extend the flash memory life expectancy.

  • Reduce the use of resources by reducing the number of writes to flash memory.

If option CONFIG_EMDS is enabled, the Light xyL Server continues to store the default xyL and range states to the flash memory through the settings library, but the last known Lightness, x, and y levels are stored by using the EMDS library. The values stored by EMDS will be lost at first boot when the CONFIG_EMDS is enabled. This split is done so the values that may change often are stored on shutdown only, while the rarely changed values are immediately stored in flash memory.

API documentation

Header file: include/bluetooth/mesh/light_xyl_srv.h
Source file: subsys/bluetooth/mesh/light_xyl_srv.c
group bt_mesh_light_xyl_srv

API for the Light xyL Server model.

Defines

BT_MESH_LIGHT_XYL_SRV_INIT(_lightness_srv, _light_xyl_handlers)

initialization parameters for a Light xyL Server model instance.

Parameters:
  • _lightness_srv[in] Pointer to Lightness server instance.

  • _light_xyl_handlers[in] Light xyL server callbacks.

BT_MESH_MODEL_LIGHT_XYL_SRV(_srv)

Light XYL Server model composition data entry.

Parameters:

Functions

int bt_mesh_light_xyl_srv_pub(struct bt_mesh_light_xyl_srv *srv, struct bt_mesh_msg_ctx *ctx, struct bt_mesh_light_xyl_status *status)

Publish the current xyL status.

Asynchronously publishes a xyL status message with the configured publish parameters.

Note

This API is only used publishing unprompted status messages. Response messages for get and set messages are handled internally.

Parameters:
  • srv[in] Server instance to publish on.

  • ctx[in] Message context to send with, or NULL to send with the default publish parameters.

  • status[in] Current status.

Return values:
  • 0 – Successfully sent the message.

  • -EADDRNOTAVAIL – A message context was not provided and publishing is not configured.

  • -EAGAIN – The device has not been provisioned.

int bt_mesh_light_xyl_srv_target_pub(struct bt_mesh_light_xyl_srv *srv, struct bt_mesh_msg_ctx *ctx, struct bt_mesh_light_xyl_status *status)

Publish the current xyL target status.

Asynchronously publishes a xyL target status message with the configured publish parameters.

Note

This API is only used publishing unprompted status messages. Response messages for get and set messages are handled internally.

Parameters:
  • srv[in] Server instance to publish on.

  • ctx[in] Message context to send with, or NULL to send with the default publish parameters.

  • status[in] Current status.

Return values:
  • 0 – Successfully sent the message.

  • -EADDRNOTAVAIL – A message context was not provided and publishing is not configured.

  • -EAGAIN – The device has not been provisioned.

int bt_mesh_light_xyl_srv_range_pub(struct bt_mesh_light_xyl_srv *srv, struct bt_mesh_msg_ctx *ctx, enum bt_mesh_model_status status_code)

Publish the current xyL Range status.

Asynchronously publishes a xyL Range status message with the configured publish parameters.

Note

This API is only used publishing unprompted status messages. Response messages for get and set messages are handled internally.

Parameters:
  • srv[in] Server instance to publish on.

  • ctx[in] Message context to send with, or NULL to send with the default publish parameters.

  • status_code[in] The status code of the response.

Return values:
  • 0 – Successfully sent the message.

  • -EADDRNOTAVAIL – A message context was not provided and publishing is not configured.

  • -EAGAIN – The device has not been provisioned.

int bt_mesh_light_xyl_srv_default_pub(struct bt_mesh_light_xyl_srv *srv, struct bt_mesh_msg_ctx *ctx)

Publish the current xyL Default parameter status.

Asynchronously publishes a xyL Default parameter status message with the configured publish parameters.

Note

This API is only used publishing unprompted status messages. Response messages for get and set messages are handled internally.

Parameters:
  • srv[in] Server instance to publish on.

  • ctx[in] Message context to send with, or NULL to send with the default publish parameters.

Return values:
  • 0 – Successfully sent the message.

  • -EADDRNOTAVAIL – A message context was not provided and publishing is not configured.

  • -EAGAIN – The device has not been provisioned.

struct bt_mesh_light_xy_set
#include <light_xyl_srv.h>

Light xy set parameters.

Public Members

struct bt_mesh_light_xy params

xy set parameters

struct bt_mesh_model_transition *transition

Transition time parameters for the state change, or NULL.

When sending, setting the transition to NULL makes the receiver use its default transition time parameters, or 0 if no default transition time is set.

struct bt_mesh_light_xy_status
#include <light_xyl_srv.h>

Light xy status response parameters.

Public Members

struct bt_mesh_light_xy current

Current xy parameters

struct bt_mesh_light_xy target

Target xy parameters

int32_t remaining_time

Remaining time for the state change (ms).

struct bt_mesh_light_xyl_srv_handlers
#include <light_xyl_srv.h>

Light xyL Server state access handlers.

Public Members

void (*const xy_set)(struct bt_mesh_light_xyl_srv *srv, struct bt_mesh_msg_ctx *ctx, const struct bt_mesh_light_xy_set *set, struct bt_mesh_light_xy_status *rsp)

Set the xy state.

When a set message is received, the model publishes a status message, with the response set to rsp. When an acknowledged set message is received, the model also sends a response back to a client. If a state change is non-instantaneous, for example when bt_mesh_model_transition_time returns a nonzero value, the application is responsible for publishing a value of the xy state at the end of the transition.

Note

This handler is mandatory.

Param srv:

[in] Server to set the xy state of.

Param ctx:

[in] Message context.

Param set:

[in] Parameters of the state change.

Param rsp:

[out] Response structure to be filled.

void (*const xy_get)(struct bt_mesh_light_xyl_srv *srv, struct bt_mesh_msg_ctx *ctx, struct bt_mesh_light_xy_status *rsp)

Get the xy state.

Note

This handler is mandatory.

Param srv:

[in] Server to get the xy state of.

Param ctx:

[in] Message context.

Param rsp:

[out] Response structure to be filled.

void (*const range_update)(struct bt_mesh_light_xyl_srv *srv, struct bt_mesh_msg_ctx *ctx, const struct bt_mesh_light_xy_range *old_range, const struct bt_mesh_light_xy_range *new_range)

The Range state has changed.

Param srv:

[in] Server the Range state was changed on.

Param ctx:

[in] Context of the set message that triggered the update.

Param old_range:

[in] The old Range.

Param new_range:

[in] The new Range.

void (*const default_update)(struct bt_mesh_light_xyl_srv *srv, struct bt_mesh_msg_ctx *ctx, const struct bt_mesh_light_xy *old_default, const struct bt_mesh_light_xy *new_default)

The Default Parameter state has changed.

Param srv:

[in] Server the Default Parameter state was changed on.

Param ctx:

[in] Context of the set message that triggered the update.

Param old_default:

[in] The old Default Parameters.

Param new_default:

[in] The new Default Parameters.

struct bt_mesh_light_xyl_srv
#include <light_xyl_srv.h>

Light xyL Server instance. Should be initialized with BT_MESH_LIGHT_XYL_SRV_INIT.

Public Members

const struct bt_mesh_model *model

Model entry.

struct bt_mesh_lightness_srv *lightness_srv

Pointer to Lightness Server instance.

struct bt_mesh_model_pub pub

Publish parameters.

struct bt_mesh_tid_ctx prev_transaction

Transaction ID tracker for the set messages.

struct bt_mesh_light_xy_range range

Current range parameters

const struct bt_mesh_light_xyl_srv_handlers *handlers

Handler function structure.

struct bt_mesh_light_xy xy_default

The default xy Level.

struct bt_mesh_light_xy xy_last

The last known xy Level.