Light Lightness Control Server¶
The Light Lightness Control (LC) Server controls a single Light Lightness Server instance on the same device with a state machine.
The state machine defines common behavior for a light fixture through three states, each with its own timing parameters and light levels. As input to its state machine, the Light LC Server listens for Sensor and OnOff messages.
In addition to the state machine, the Light LC Server may optionally use a regulator to control the ambient illuminance in the room. The regulator requires illuminance sensor readings acting as feedback for its regulator loop.
The Lightness Control Server is always disabled by default, and must be enabled by a Light Lightness Control Client.
Overview¶
In this section, you can find more detailed information about the following aspects of the Light LC Server:
Composition data structure¶
As both the Light LC Server and the Light Lightness Server extend the Generic OnOff model, the two models cannot be instantiated on the same element.
Note
Due to implementation limitations, the Light LC Server is instantiated on the next element after the Light Lightness Server it is controlling.
In the application, this composition data looks like this:
static struct bt_mesh_elem elements[] = {
/* Lightness element */
BT_MESH_ELEM(1,
BT_MESH_MODEL_LIST(BT_MESH_MODEL_LIGHTNESS_SRV(&lightness_srv)),
BT_MESH_MODEL_NONE),
/* Light Control element */
BT_MESH_ELEM(2,
BT_MESH_MODEL_LIST(BT_MESH_MODEL_LIGHT_CTRL_SRV(&light_ctrl_srv)),
BT_MESH_MODEL_NONE),
};
The Light LC Server will log an error during initialization if the controlled Lightness Server is on the same element.
Relationship with other nodes¶
When the Light LC Server model controls a Light Lightness Server, all nodes should publish to the LC Server or its extended Generic OnOff model, instead of publishing directly to the Light Lightness Server:
The dimmer devices that want to override the light level of the Lightness Server can publish directly to the Lightness Server. This disengages the Light LC Server, and the Lightness Server operates independently until the Light LC Server is explicitly re-enabled.
Lightness state machine¶
The Light LC Server’s lightness state machine operates in the following states:
- Standby
There is no activity in the room, and the device’s light are either off or dimmed.
- On
There is activity in the room, and the lights are on.
- Prolong
There is no activity detected. The lights are at a slightly dimmed level, ready to get back to their On level as soon as activity is detected.
Each state has a lightness level and a transition time used for fading. When the state changes, the light level fades from the previous state’s level to the new state’s level in a transition time span determined by the new state.
When the Light LC Server is turned on, the following sequence takes place:
The state machine cycles through the states with the following events:
- Timeout
Triggered when the current state has timed out. The state machine automatically moves into the next state.
- On
Toggled when a motion sensor is triggered or the On button is pressed on a light switch.
- Off
Toggled when the Off button is pressed on a light switch.
The On and Prolong states will start a timer as soon as the transition into the state is finished. When this timer expires, the state machine will automatically go into the next state. If the On event is triggered while in the On state, the timer is reset, and the transition to the Prolong state is postponed.
Note
The state machine only works while the Light LC Server is enabled, and it always starts in the Standby state.
Resuming the state machine operation¶
Whenever something but the Light LC Server interacts with the controlled Lightness Server, the Light LC Server disables its state machine, and the Lightness Server starts running independently. To resume the state machine operation, the Light LC Server must be explicitly re-enabled.
To avoid having a Lightness Server running independently forever, the Light LC Server implements a resume timer that lets the Light LC Server regain control after being disabled for a certain number of seconds.
The resume timer can be configured with the CONFIG_BT_MESH_LIGHT_CTRL_SRV_RESUME_DELAY
option, and is disabled by default.
Note
The resume timer does not exist in the Bluetooth mesh specification, and may become incompatible with future specification changes. Although it does not break the specification or qualification tests in the current iteration of the Bluetooth mesh specification, its behavior may be unexpected for third party devices, and should be used with caution.
State machine outputs¶
The state machine has two different output values for each state:
- Light level
The light level decides the output light level sent to the controlled Light Lightness Server. Each state has a configurable light level, and the output light level will be the light level of the current state, with linear transitions between the states. The default light level values per state are:
Standby state - 0%
On state - 100%
Prolong state - 50%
- Target illuminance level
Each state has a configurable target illuminance level, which is used as input to the Illuminance regulator. The target illuminance level decides the ambient illuminance the regulator should try to achieve, as measured by illuminance sensors nearby. Just like with the light level, the target illuminance always matches the configured target illuminance for the current state, with linear transitions between the states.
External event triggers¶
While the Timeout event is controlled internally, the On and Off events are produced by external behavior.
On event¶
The On event lets the Light LC Server know that there is activity in the room. It can be generated by light switches and sensors.
Light switches can implement one of the following models to send On messages that turn the Light LC Server on:
The Generic OnOff Client model – which should publish to the Light LC Server’s extended Generic OnOff Server model.
The Light Lightness Control Client model – which should publish Light OnOff Set messages to the Light LC Server.
Occupancy sensors can also trigger the On event, depending on the current state and occupancy mode:
If the occupancy mode is enabled, sensor readings that indicate activity can trigger an On event at any time.
If the occupancy mode is disabled, sensors cannot turn the lights on, but they will still prevent lights from turning off.
The following sensor types can also trigger the On event:
- Motion sensed -
bt_mesh_sensor_motion_sensed
Any sensor value higher than 0 triggers an On event in the Light LC Server state machine. Messages with a value of 0 are ignored.
- People count -
bt_mesh_sensor_people_count
Any sensor value higher than
0
triggers an On event in the Light LC Server state machine. Messages with a value of0
are ignored.- Presence detected -
bt_mesh_sensor_presence_detected
Messages with a
true
value triggers an On event in the Light LC Server state machine. Messages with afalse
value are ignored.- Time since motion sensed -
bt_mesh_sensor_time_since_motion_sensed
When the sensor’s Time since motion sensed value is lower than the Light LC Server’s occupancy delay, the Light LC Server starts a timer that expires at the time equal to Motion sensed plus occupancy delay. When this timer expires, an On event is generated.
Note
Only sensors reporting the Time since motion sensed type will be affected by the occupancy delay. Other sensor triggers are always instantaneous.
Off event¶
The Off event can only be generated by a light switch being turned off.
It moves the Light LC Server into Standby, transitioning from the previous light level with the manual mode Standby fade time (BT_MESH_LIGHT_CTRL_PROP_TIME_FADE_STANDBY_MANUAL
).
The Off event puts the Light LC Server into manual mode, which disables sensor input until the manual mode timeout (CONFIG_BT_MESH_LIGHT_CTRL_SRV_TIME_MANUAL
) expires.
This prevents the lights from turning back on by the movement of the person that presses the light switch.
Note
Unlike other timing parameters, the manual mode timeout is proprietary and cannot be reconfigured at runtime by other models in the mesh network.
Light switches can implement one of the following clients to send Off messages that turn the Light LC Server on:
Generic OnOff Client - This model should publish to the Light LC Server’s extended Generic OnOff Server model.
Light Lightness Control Client - This model should publish Light OnOff Set messages to the Light LC Server.
If a Timeout transition from Prolong to Standby is already in progress, the Light LC Server will check whether the remaining transition time is shorter than the Off event fade time and will execute whichever is the fastest.
State machine configuration¶
Both the timing and output levels are configurable at compile time and at runtime:
The compile time configuration is done through the Light Control Server Kconfig menu options.
The runtime configuration must be done by a Light Control Client model instance through the Light Lightness Controller Setup Server.
Timing parameters¶
This section lists compile and runtime options to be used when setting timing parameters.
- Delay from occupancy detected until light turns on
Compile time:
CONFIG_BT_MESH_LIGHT_CTRL_SRV_OCCUPANCY_DELAY
- Transition time to On state
Compile time:
CONFIG_BT_MESH_LIGHT_CTRL_SRV_TIME_FADE_ON
Runtime:
BT_MESH_LIGHT_CTRL_PROP_TIME_FADE_ON
- Time in On state
Compile time:
CONFIG_BT_MESH_LIGHT_CTRL_SRV_TIME_ON
Runtime:
BT_MESH_LIGHT_CTRL_PROP_TIME_ON
- Transition time to Prolong state
Compile time:
CONFIG_BT_MESH_LIGHT_CTRL_SRV_TIME_FADE_PROLONG
- Time in Prolong state
Compile time:
CONFIG_BT_MESH_LIGHT_CTRL_SRV_TIME_PROLONG
Runtime:
BT_MESH_LIGHT_CTRL_PROP_TIME_PROLONG
- Transition time to Standby state (in auto mode)
- Transition time to Standby state (in manual mode)
- Manual mode timeout
Compile time:
CONFIG_BT_MESH_LIGHT_CTRL_SRV_TIME_MANUAL
No runtime option available.
Output parameters¶
This section lists compile and runtime options to be used when setting output parameters.
- On state light level
Compile time:
CONFIG_BT_MESH_LIGHT_CTRL_SRV_LVL_ON
Runtime:
BT_MESH_LIGHT_CTRL_LIGHTNESS_ON
- Prolong state light level
Compile time:
CONFIG_BT_MESH_LIGHT_CTRL_SRV_LVL_PROLONG
Runtime:
BT_MESH_LIGHT_CTRL_LIGHTNESS_PROLONG
- Standby state light level
Compile time:
CONFIG_BT_MESH_LIGHT_CTRL_SRV_LVL_STANDBY
Runtime:
BT_MESH_LIGHT_CTRL_LIGHTNESS_STANDBY
- On state target illuminance
Compile time:
CONFIG_BT_MESH_LIGHT_CTRL_SRV_REG_LUX_ON
- Prolong state target illuminance
Compile time:
CONFIG_BT_MESH_LIGHT_CTRL_SRV_REG_LUX_PROLONG
- Standby state target illuminance
Compile time:
CONFIG_BT_MESH_LIGHT_CTRL_SRV_REG_LUX_STANDBY
Illuminance regulator¶
The illuminance regulator complements the light level state machine by adding an ambient illuminance sensor feedback loop. This allows the Lightness Server to adjust its output level that is based on the room’s ambient light, and as a result conserve energy and achieve more consistent light levels.
The illuminance regulator takes the state machine’s target illuminance level as the reference level and compares it to sensor data from an external illuminance sensor. The inputs are compared to establish an error for the regulator, which the regulator tries to minimize. The regulator contains a proportional (P) and an integral (I) component whose outputs are summarized to a light level output.
The illuminance regulator’s output level only comes into effect if the required output level is higher than the state machine’s output light level. To get full benefit of the regulator, the state machine’s light level output should generally be configured to a lower value than desired, while keeping the target illuminance levels high. This allows the regulator to conserve energy by taking advantage of the room’s ambient lighting.
The regulator operates in a compile time configurable interval between 10 and 100 ms. For each step, the regulator:
Calculates the integral of the error since the last step.
Adds the integral to an internal sum.
Multiplies this sum by an integral coefficient.
Summarizes the sum with the raw difference multiplied by a proportional coefficient.
The error, the regulator coefficients, and the internal sum, are represented as 32-bit floating point values. The resulting output level is represented as an unsigned 16-bit integer.
To reduce noise, the regulator has a configurable accuracy property, which allows it to ignore errors smaller than the configured accuracy (represented as a percentage of the light level).
See CONFIG_BT_MESH_LIGHT_CTRL_SRV_REG_ACCURACY
and BT_MESH_LIGHT_CTRL_PROP_REG_ACCURACY
for more information.
Sensor input¶
The regulator relies on regular sensor input data to function correctly.
This sensor data must come from an external Sensor Server model and report the ambient light level with the bt_mesh_sensor_present_amb_light_level
sensor type.
The Sensor Server should publish its sensor readings to an address the Light LC Server is subscribed to, using a common application key.
The Light LC Server will process all incoming sensor messages and use them in the next regulator step. The regulator depends on frequent readings from the sensor server to provide a stable output for the Lightness Server. If the sensor reports are too slow, the regulator might oscillate, as it attempts to compensate for outdated feedback.
Tip
Use the Sensor Delta threshold feature for ambient light sensors feeding the regulator. This makes the sensor send frequent reports when the regulator is compensating for large errors, while keeping the mesh traffic low in stable periods.
The Sensor Server may be instantiated on the same mesh node as the Light LC Server, or on a different mesh node in the same area. The regulator performance depends heavily on the sensor’s placement and sensitivity. In general, ambient light sensor devices should be placed in a way that allows their light sensor to capture the human perception of the room’s light level as closely as possible.
Tuning the regulator¶
Regulator tuning is complex and depends on a lot of internal and external parameters. Varying sensor delay, light output and light change rate may significantly affect the regulator performance and accuracy. To compensate for the external parameters, each regulator component provides user controllable coefficients that change their impact on the output value:
Kp - for the proportional component
Ki - for the integral component
These coefficients can have individual values for positive and negative errors, referenced as follows in the API:
Kpu - proportional up; used when target is higher.
Kpd - proportional down; used when target is lower.
Kiu - integral up; used when target is higher.
Kid - integral down; used when target is lower
Regulators are tuned to fit their environment by changing the coefficients. The coefficient adjustments are typically done by analyzing the system’s step response. The step response is the overall system response to a change in reference value, for instance in a state change in the light level state machine.
Note
The transition time between states in the Light LC Server makes the feedback loop more forgiving. A larger transition time can compensate for poor regulator response.
The illuminance regulator is a PI regulator, which uses the following components to compensate for a mismatch between the reference and the measured level:
Instantaneous error - The proportional component that is typically the main source of correction for a PI regulator. It compares the reference value to the most recent feedback value, and attempts to correct the error by eliminating the difference.
Accumulated error - The integral component that compensates for errors by adding up the sum of the error over time. Its main contribution is to eliminate system bias and accelerate the system step response.
Changing different coefficients will affect the step response differently. Increasing the two coefficients will have the following effect on the step response:
Coefficient |
Rise time |
Overshoot |
Settling time |
Steady-state error |
---|---|---|---|---|
Kp |
Faster |
Higher |
- |
- |
Ki |
Faster |
Higher |
Longer |
Reduced |
The value of the coefficients is typically a trade-off between fast response time and system instability:
If the value is too high, the system might become unstable, potentially leading to oscillation and loss of control.
If the value is too low, the step response might be too slow or unable to reach the target value altogether.
States¶
Not to be confused with the state machine states, the Light LC Server’s states represent its current mode of operation and configuration.
- Mode:
bool
Enables or disables the Light LC Server. When disabled, the controlled Lightness Server operates independently.
- Occupancy mode:
bool
The occupancy mode controls whether sensor activity can turn the lights on. If disabled, motion and occupancy sensor messages may only prevent the lights from turning off, and a light switch is required to turn them on.
- Light OnOff:
bool
When set, the Light OnOff state may trigger transactions in the lightness state machine. When read, the Light OnOff state indicates whether the lights are turned off (in the Standby state) or on (in the On state or the Prolong state).
- Properties
The Light Control Properties are used to configure the Light LC Server behavior. See
bt_mesh_light_ctrl_prop
for a list of supported properties and their representation.
Extended models¶
The Light LC Server extends the following models:
Additionally, it requires a Light Lightness Server it can control, instantiated in a different element. See the Composition data structure section for details.
Persistent Storage¶
If CONFIG_BT_SETTINGS
is enabled, the Light LC Server stores all its states persistently using a configurable storage delay to stagger storing.
See CONFIG_BT_MESH_MODEL_SRV_STORE_TIMEOUT
.
Changes to the configuration properties are stored and restored on power-up, so the compile time configuration is only valid the first time the device powers up, until the configuration is changed.
Power-up behavior¶
When powering up, the Light LC Server behavior depends on the controlled Lightness Server’s extended Generic Power OnOff Server’s state:
On Power Up is
BT_MESH_ON_POWER_UP_OFF
- The Light LC Server is disabled, and the Lightness Server remains off.On Power Up is
BT_MESH_ON_POWER_UP_ON
- The Light LC Server is disabled, and the Lightness Server light level is set to its default value.On Power Up is
BT_MESH_ON_POWER_UP_RESTORE
- The Light LC Server is enabled and takes control of the Lightness Server. If the last known value of the Light OnOff state was On, the Light LC Server triggers a transition to the On state.
Warning
The Light LC Server is only re-enabled on startup if the Lightness Server’s extended Generic Power OnOff Server is in the restore mode.
API documentation¶
include/bluetooth/mesh/light_ctrl_srv.h
subsys/bluetooth/mesh/light_ctrl_srv.c
-
group
bt_mesh_light_ctrl_srv
Light Lightness Control Server model API.
Defines
-
BT_MESH_LIGHT_CTRL_SRV_INIT
(_lightness_srv)¶ Initialization parameters for Light Lightness Control Server.
- Parameters
_lightness_srv – [in] Pointer to the Light Lightness Server model this server controls.
-
BT_MESH_MODEL_LIGHT_CTRL_SRV
(_srv)¶ Light Lightness model entry.
- Parameters
_srv – [in] Pointer to a Light Lightness Control Server instance.
Enums
Functions
-
int
bt_mesh_light_ctrl_srv_on
(struct bt_mesh_light_ctrl_srv *srv)¶ Turn the light on.
Instructs the controlled Lightness Server to turn the light on. If the light was already on, the dimming timeout is reset. If the light was in the Prolong state, it’s moved back into the On state.
- Parameters
srv – [in] Light Lightness Control Server instance.
- Returns 0
The Light Lightness Control Server was successfully turned on.
- Returns -EBUSY
The Light Lightness Control Server is disabled.
-
int
bt_mesh_light_ctrl_srv_off
(struct bt_mesh_light_ctrl_srv *srv)¶ Manually turn the light off.
Instructs the controlled Lightness Server to turn the light off (Standby state). Calling this function temporarily disables occupancy sensor triggering (referred to as “manual mode” in the documentation). The server will remain in manual mode until the manual mode timer expires, see
CONFIG_BT_MESH_LIGHT_CTRL_SRV_TIME_MANUAL
.- Parameters
srv – [in] Light Lightness Control Server instance.
- Returns 0
The Light Lightness Control Server was successfully turned off.
- Returns -EBUSY
The Light Lightness Control Server is disabled.
-
int
bt_mesh_light_ctrl_srv_enable
(struct bt_mesh_light_ctrl_srv *srv)¶ Enable the Light Lightness Control Server.
The Server must be enabled to take control of the Lightness Server.
- Parameters
srv – [in] Light Lightness Control Server instance.
- Returns 0
The Light Lightness Control Server was successfully enabled.
- Returns -EALREADY
The Light Lightness Control Server was already enabled.
-
int
bt_mesh_light_ctrl_srv_disable
(struct bt_mesh_light_ctrl_srv *srv)¶ Disable the Light Lightness Control Server.
The server must be enabled to take control of the Lightness Server. Disabling the server disengages the control over the Lightness Server, which will start running as an independent model.
- Parameters
srv – [in] Light Lightness Control Server instance.
- Returns 0
The Light Lightness Control Server was successfully enabled.
- Returns -EALREADY
The Light Lightness Control Server was already enabled.
-
bool
bt_mesh_light_ctrl_srv_is_on
(struct bt_mesh_light_ctrl_srv *srv)¶ Check if the Light Lightness Control Server has turned the light on.
- Parameters
srv – [in] Light Lightness Control Server instance.
- Returns
true if the Lightness Server’s light is on because of its binding with the Light Lightness Control Server, false otherwise.
-
int
bt_mesh_light_ctrl_srv_pub
(struct bt_mesh_light_ctrl_srv *srv, struct bt_mesh_msg_ctx *ctx)¶ Publish the current OnOff state.
- Parameters
srv – [in] Light Lightness Control Server instance.
ctx – [in] Message context, or NULL to publish with the configured parameters.
- Returns -EADDRNOTAVAIL
A message context was not provided and publishing is not configured.
- Returns -EAGAIN
The device has not been provisioned.
- Returns
0 Successfully published the current Light state.
-
struct
bt_mesh_light_ctrl_srv_cfg
¶ - #include <light_ctrl_srv.h>
Light Lightness Control Server configuration.
Public Members
-
uint32_t
occupancy_delay
¶ Delay from occupancy detected until light turns on.
-
uint32_t
fade_on
¶ Transition time to On state.
-
uint32_t
on
¶ Time in On state.
-
uint32_t
fade_prolong
¶ Transition time to Prolong state.
-
uint32_t
prolong
¶ Time in Prolong state.
-
uint32_t
fade_standby_auto
¶ Transition time to Standby state (in auto mode).
-
uint32_t
fade_standby_manual
¶ Transition time to Standby state (in manual mode).
-
uint16_t
light
[LIGHT_CTRL_STATE_COUNT
]¶ State-wise light levels
-
uint32_t
-
struct
bt_mesh_light_ctrl_srv_reg_cfg
¶ - #include <light_ctrl_srv.h>
Illumination regulator configuration
Public Members
-
struct sensor_value
lux
[LIGHT_CTRL_STATE_COUNT
]¶ Target illuminance values
-
float
kiu
¶ Regulator upwards integral coefficient
-
float
kid
¶ Regulator downwards integral coefficient
-
float
kpu
¶ Regulator upwards propotional coefficient
-
float
kpd
¶ Regulator downwards propotional coefficient
-
uint8_t
accuracy
¶ Regulator dead zone (in percent)
-
struct sensor_value
-
struct
bt_mesh_light_ctrl_srv_reg
¶ - #include <light_ctrl_srv.h>
Illumination regulator
Public Members
-
struct k_work_delayable
timer
¶ Regulator step timer
-
float
i
¶ Internal integral sum.
-
uint16_t
prev
¶ Previous output
-
struct bt_mesh_light_ctrl_srv_reg_cfg
cfg
¶ Regulator configuration
-
struct k_work_delayable
-
struct
bt_mesh_light_ctrl_srv
¶ - #include <light_ctrl_srv.h>
Light Lightness Control Server instance.
Should be initialized with BT_MESH_LIGHT_CTRL_SRV_INIT.
Public Members
-
enum bt_mesh_light_ctrl_srv_state
state
¶ Current control state
-
atomic_t
flags
¶ Internal flag field
-
uint16_t
initial_light
¶ Initial light level
-
struct sensor_value
initial_lux
¶ Initial illumination level
-
uint32_t
duration
¶ Fade duration
-
struct bt_mesh_light_ctrl_srv.[anonymous]
fade
¶ Parameters for the start of current state
-
struct sensor_value
ambient_lux
¶ Present ambient illumination
-
struct k_work_delayable
timer
¶ State timer
-
struct k_work_delayable
action_delay
¶ Timer for delayed action
-
struct bt_mesh_light_ctrl_srv_cfg
cfg
¶ Configuration parameters
-
struct bt_mesh_model_pub
pub
¶ Publish parameters
-
struct bt_mesh_model_pub
setup_pub
¶ Setup model publish parameters
-
struct bt_mesh_lightness_srv *
lightness
¶ Lightness server instance
-
struct bt_mesh_onoff_srv
onoff
¶ Extended Generic OnOff server
-
struct bt_mesh_tid_ctx
tid
¶ Transaction ID tracking context
-
struct bt_mesh_model *
model
¶ Composition data server model instance
-
struct bt_mesh_model *
setup_srv
¶ Composition data setup server model instance
-
enum bt_mesh_light_ctrl_srv_state
-