Bluetooth Mesh sensors
Note
A new sensor API is introduced as of nRF Connect SDK v2.6.0.
The old API is deprecated, but still available by enabling the Kconfig option CONFIG_BT_MESH_SENSOR_USE_LEGACY_SENSOR_VALUE
.
The Kconfig option is enabled by default in the deprecation period.
See the documentation for nRF Connect SDK versions prior to v2.6.0 for documentation about the old sensor API.
The Bluetooth® Mesh specification provides a common scheme for representing all sensors. A single Bluetooth Mesh sensor instance represents a single physical sensor, and a mesh device may present any number of sensors to the network through a Sensor Server model. Sensors represent their measurements as a list of sensor channels, as described by the sensor’s assigned type.
Sensors are accessed through the Sensor models, which are documented separately:
Note
Several floating point computations are done internally in the stack when using the sensor API.
It is recommended to enable the CONFIG_FPU
Kconfig option to improve the performance of these computations.
Basic example
A sensor reporting the device operating temperature could combine the Bluetooth Mesh Present Device Operating Temperature
sensor type with the on-chip TEMP_NRF5
temperature sensor driver:
static const struct device *dev = DEVICE_DT_GET_ONE(nordic_nrf_temp);
static int temp_get(struct bt_mesh_sensor *sensor,
struct bt_mesh_msg_ctx *ctx,
struct bt_mesh_sensor_value *rsp)
{
struct sensor_value value;
int err;
sensor_sample_fetch(dev);
err = sensor_channel_get(dev, SENSOR_CHAN_DIE_TEMP, &value);
if (err) {
return err;
}
return bt_mesh_sensor_value_from_sensor_value(&value, rsp);
}
struct bt_mesh_sensor temp_sensor = {
.type = &bt_mesh_sensor_present_dev_op_temp,
.get = temp_get,
};
void init(void)
{
__ASSERT(device_is_ready(dev), "Sensor device not ready");
}
Additionally, a pointer to the temp_sensor
structure should be passed to a Sensor Server to be exposed to the mesh.
See Sensor Server for details.
Sensor values
Sensor values are represented in the API using bt_mesh_sensor_value
.
This contains the raw sensor value, encoded according to a certain Bluetooth GATT Characteristic, and a pointer to bt_mesh_sensor_format
describing how that characteristic is encoded/decoded.
Applications will normally not access bt_mesh_sensor_value.raw
or the members of bt_mesh_sensor_value.format
directly.
Instead, API functions for converting between bt_mesh_sensor_value
and the values suitable for application use are used.
An exception to this is when statically initializing bt_mesh_sensor_value
at compile-time, in which case the API functions cannot be used.
The sensor API is built to integrate well with the Zephyr Sensors API, and provides functions for converting to and from sensor_value
.
Sensor types
Sensor types are the specification defined data types for the various Bluetooth Mesh sensor parameters. Each sensor type is assigned its own Device Property ID, as specified in the Bluetooth Mesh device properties specification. Like the Device Properties, the Sensor types are connected to a Bluetooth GATT Characteristic, which describes the unit, range, resolution and encoding scheme of the sensor type.
Note
The Bluetooth Mesh specification only allows sensor types that have a Device Property ID in the Bluetooth Mesh device properties specification. It’s not possible to represent vendor specific sensor values.
The sensor types may either be used as the data types of the sensor output values, or as configuration parameters for the sensors.
Sensor channels
Each sensor type may consist of one or more channels. The list of sensor channels in each sensor type is immutable, and all channels must always have a valid value when the sensor data is passed around. This is slightly different from the sensor type representation in the Bluetooth Mesh specification, which represents multi-channel sensors as structures, rather than flat lists.
Each channel in a sensor type is represented by a single bt_mesh_sensor_value
structure.
This contains the raw value of the sensor value, and a pointer to bt_mesh_sensor_format
used for encoding and decoding of the raw value.
Every sensor channel has a name and a unit, as listed in the sensor type documentation.
The name and unit are only available if CONFIG_BT_MESH_SENSOR_LABELS
option is set, and can aid in debugging and presentation of the sensor output.
Both the channel name and unit is also listed in the documentation for each sensor type.
Most sensor values are reported as scalars with some scaling factor applied to them during encoding. This scaling factor and the encoded data type determines the resolution and range of the sensor data in a specific channel. For instance, if a sensor channel measuring electric current has a resolution of 0.5 Ampere, this is the highest resolution value other mesh devices will be able to read out from the sensor. Before encoding, the sensor values are rounded to their nearest available representation, so the following sensor value would be read as 7.5 Ampere:
struct bt_mesh_sensor_value sensor_val;
/* Sensor value: 7.3123 A */
(void)bt_mesh_sensor_value_from_float(
&bt_mesh_sensor_format_electric_current,
7.3123f, &sensor_val);
Various other encoding schemes are used to represent non-scalars. See the documentation or specification for the individual sensor channels for more details.
Sensor series types
The sensor series functionality may be used for all sensor types. However, some sensor types are made specifically for being used in a sensor series. These sensor types have one primary channel containing the sensor data and two secondary channels that denote some interval in which the primary channel’s data is captured. Together, the three channels are able to represent historical sensor data as a histogram, and Sensor Client models may request access to specific measurement spans from a Sensor Server model.
The unit of the measurement span is defined by the sensor type, and will typically be a time interval or a range of operational parameters, like temperature or voltage level.
For instance, the bt_mesh_sensor_rel_dev_energy_use_in_a_period_of_day
sensor type represents the energy used by the device in specific periods of the day.
The primary channel of this sensor type measures energy usage in kWh, and the secondary channels denote the timespan in which the specific energy usage was measured.
A sensor of this type may be queried for specific measurement periods measured in hours, and should provide the registered energy usage only for the requested time span.
Sensor setting types
Some sensor types are made specifically to act as sensor settings.
These values are encoded the same way as other sensor types, but typically represent a configurable sensor setting or some specification value assigned to the sensor from the manufacturer.
For instance, the bt_mesh_sensor_motion_threshold
sensor type can be used to configure the sensitivity of a sensor reporting motion sensor data (bt_mesh_sensor_motion_sensed
).
Typically, settings should only be meta data related to the sensor data type, but the API contains no restrictions for which sensor types can be used for sensor settings.
Available sensor types
All available sensor types are collected in the Bluetooth Mesh sensor formats and sensor types module.
Sample data reporting
Sensors may report their values to the mesh in three ways:
Unprompted publications
Periodic publication
Polling
Unprompted publications may be done at any time, and only includes the sensor data of a single sensor at a time.
The application may generate an unprompted publication by calling bt_mesh_sensor_srv_sample()
.
This triggers the sensor’s bt_mesh_sensor.get
callback, and only publishes if the sensor’s Delta threshold is satisfied.
Unprompted publications can also be forced by calling bt_mesh_sensor_srv_pub()
directly.
Periodic publication is controlled by the Sensor Server model’s publication parameters, and configured by the Config models. The sensor Server model reports data for all its sensor instances periodically, at a rate determined by the sensors’ cadence. Every publication interval, the Server consolidates a list of sensors to include in the publication, and requests the most recent data from each. The combined data of all these sensors is published as a single message for other nodes in the mesh network.
If no publication parameters are configured for the Sensor Server model, Sensor Client models may poll the most recent sensor samples directly.
All three methods of reporting may be combined.
Cadence
Each sensor may use the cadence state to control the rate at which their data is published. The sensor’s publication interval is defined as a divisor of the holding sensor Server’s publication interval that is always a power of two. Under normal circumstances, the sensor’s period divisor is always 1, and the sensor only publishes on the Server’s actual publication interval.
All single-channel sensors have a configurable fast cadence range that automatically controls the sensor cadence. If the sensor’s value is within its configured fast cadence range, the sensor engages the period divisor, and starts publishing with fast cadence.
The fast cadence range always starts at the cadence range low
value, and spans to the cadence range high
value.
If the high
value is lower than the low
value, the effect is inverted, and the sensor operates at high cadence if its value is outside the range.
To prevent sensors from saturating the mesh network, each sensor also defines a minimum publication interval, which is always taken into account when performing the period division.
The period divisor, fast cadence range and minimum interval is configured by a Sensor Client model (through a Sensor Setup Server). The sensor’s cadence is automatically recalculated for every sample, based on its configuration.
Delta threshold
All single channel sensors have a delta threshold state to aid the publication rate. The delta threshold state determines the smallest change in sensor value that should trigger a publication. Whenever a sensor value is published to the mesh network (through periodic publishing or otherwise), the sensor saves the value, and compares it to subsequent samples. Once a sample is sufficiently far away from the previously published value, it gets published.
The delta threshold works on both periodic publication and unprompted publications. If periodic publication is enabled and the minimum interval has expired, the sensor will periodically check whether the delta threshold has been breached, so that it can publish the value on the next periodic interval.
The delta threshold may either be specified as a percent wise change, or as an absolute delta. The percent wise change is always measured relatively to the previously published value, and allows the sensor to automatically scale its threshold to account for relative inaccuracy or noise.
The sensor has separate delta thresholds for positive and negative changes.
Descriptors
Descriptors are optional meta information structures for every sensor. A sensor’s Descriptor contains parameters that may aid other mesh nodes in interpreting the data:
Tolerance
Sampling function
Measurement period
Update interval
The sensor descriptor is constant throughout the sensor’s lifetime.
If the sensor has a descriptor, a pointer to it should be passed to bt_mesh_sensor.descriptor
on init, as for example done in the code below:
static const struct bt_mesh_sensor_descriptor temp_sensor_descriptor = {
.tolerance = {
.negative = BT_MESH_SENSOR_TOLERANCE_ENCODE(0.75f)
.positive = BT_MESH_SENSOR_TOLERANCE_ENCODE(3.5f)
},
.sampling_type = BT_MESH_SENSOR_SAMPLING_ARITHMETIC_MEAN,
.period = 300,
.update_interval = 50
};
struct bt_mesh_sensor temp_sensor = {
.type = &bt_mesh_sensor_present_dev_op_temp,
.get = temp_get,
.descriptor = &temp_sensor_descriptor
};
See bt_mesh_sensor_descriptor
for details.
Usage
Sensors instances are generally static structures that are initialized at startup.
Only the bt_mesh_sensor.type
member is mandatory, the rest are optional.
Apart from the Cadence and Descriptor states, all states are accessed through getter functions.
The absence of a getter for a state marks it as not supported by the sensor.
Sensor data
Sensor data is accessed through the bt_mesh_sensor.get
callback, which is expected to fill the rsp
parameter with the most recent sensor data and return a status code.
Each sensor channel must be encoded according to the channel format.
This can be done using one of the conversion functions bt_mesh_sensor_value_from_micro()
, bt_mesh_sensor_value_from_float()
or bt_mesh_sensor_value_from_sensor_value()
.
A pointer to the format for a given channel can be found through the bt_mesh_sensor
pointer passed to the callback in a following way:
static int get_cb(struct bt_mesh_sensor *sensor,
struct bt_mesh_msg_ctx *ctx,
struct bt_mesh_sensor_value *rsp)
{
/* Get the correct format to use for encoding rsp[0]: */
const struct_bt_mesh_sensor_format *channel_0_format =
sensor->type->channels[0].format;
}
The sensor data in the callback typically comes from a sensor using the Zephyr sensor API. The Zephyr sensor API records samples in two steps:
1.
Tell the sensor to take a sample by calling sensor_sample_fetch()
.
2.
Read the recorded sample data with sensor_channel_get()
.
The first step may be done at any time.
Typically, the sensor fetching is triggered by a timer, an external event or a sensor trigger, but it may be called in the get
callback itself.
Note that the get
callback requires an immediate response, so if the sample fetching takes a significant amount of time, it should generally be done asynchronously.
The method of sampling may be communicated to other mesh nodes through the sensor’s descriptor.
The read step would typically be done in the callback, to pass the sensor data to the mesh.
If the Sensor Server is configured to do periodic publishing, the get
callback will be called for every publication interval.
Publication may also be forced by calling bt_mesh_sensor_srv_sample()
, which will trigger the get
callback and publish only if the sensor value has changed.
Sensor series
Sensor series data can be provided for all sensor types.
To enable the sensor’s series data feature, bt_mesh_sensor_series.column_count
must be specified and the sensor series bt_mesh_sensor_series.get
callback must be implemented.
For sensor types with more than two channels, the series data is organized into a static set of columns, specified at init.
The format of the column may be queried with bt_mesh_sensor_column_format_get()
.
The get
callback gets called with an index of one of the columns, and is expected to fill the value
parameter with sensor data for the specified column.
If a Sensor Client requests a series of columns, the callback may be called repeatedly, requesting data from each column.
Example: A three-channel sensor (average ambient temperature in a period of day) as a sensor series:
/* Macro for statically initializing time_decihour_8.
* Raw is computed by multiplying by 10 according to
* the resolution specified in the GATT Specification
* Supplement.
*/
#define TIME_DECIHOUR_8_INIT(_hours) { \
.format = &bt_mesh_sensor_format_time_decihour_8, \
.raw = { (_hours) * 10 } \
}
#define COLUMN_INIT(_start, _width) { \
TIME_DECIHOUR_8_INIT(_start), \
TIME_DECIHOUR_8_INIT(_width) \
}
/* 4 columns representing different hours in a day */
static const struct bt_mesh_sensor_column columns[] = {
COLUMN_INIT(0, 6),
COLUMN_INIT(6, 6),
COLUMN_INIT(12, 6),
COLUMN_INIT(18, 6)
};
static struct bt_mesh_sensor temp_sensor = {
.type = &bt_mesh_sensor_avg_amb_temp_in_day,
.series = {
columns,
ARRAY_SIZE(columns),
getter,
},
};
/** Sensor data is divided into columns and filled elsewhere */
static float avg_temp[ARRAY_SIZE(columns)];
static int getter(struct bt_mesh_sensor *sensor, struct bt_mesh_msg_ctx *ctx,
uint32_t column_index, struct bt_mesh_sensor_value *value)
{
int err = bt_mesh_sensor_value_from_float(
sensor->type->channels[0].format, &avg_temp[column_index], &value[0]);
if (err) {
return err;
}
value[1] = columns[column_index].start;
/* Compute end value from column start and width: */
int64_t start, width;
enum bt_mesh_sensor_value_status status;
status = bt_mesh_sensor_value_to_micro(&columns[column_index].start, &start);
if (!bt_mesh_sensor_status_is_numeric(status)) {
return -EINVAL;
}
status = bt_mesh_sensor_value_to_micro(&columns[column_index].width, &width);
if (!bt_mesh_sensor_value_status_is_numeric(status)) {
return -EINVAL;
}
return bt_mesh_sensor_value_from_micro(
bt_mesh_sensor_column_format_get(sensor),
start + width, &value[2]);
}
Example: Single-channel sensor (motion sensed) as a sensor series:
#define COLUMN_COUNT 10
static struct bt_mesh_sensor motion_sensor = {
.type = &bt_mesh_sensor_motion_sensed,
.series = {
/* Note: no column array necessary for 1 or 2 channel sensors */
.column_count = COLUMN_COUNT,
.get = getter,
},
};
/** Sensor data is divided into columns and filled elsewhere */
static uint8_t motion[COLUMN_COUNT];
static int getter(struct bt_mesh_sensor *sensor, struct bt_mesh_msg_ctx *ctx,
uint32_t column_index, struct bt_mesh_sensor_value *value)
{
return bt_mesh_sensor_value_from_micro(
sensor->type->channels[0].format,
motion[column_index] * 1000000LL, &value[0]);
}
Sensor settings
The list of settings a sensor supports should be set on init.
The list should be constant throughout the sensor’s lifetime, and may be declared const
.
Each entry in the list has a type and two access callbacks, and the list should only contain unique entry types.
The bt_mesh_sensor_setting.get
callback is mandatory, while the bt_mesh_sensor_setting.set
is optional, allowing for read-only entries.
The value of the settings may change at runtime, even outside the set
callback.
New values may be rejected by returning a negative error code from the set
callback.
The following code is an example of adding a setting to a sensor:
static void motion_threshold_get(struct bt_mesh_sensor_srv *srv,
struct bt_mesh_sensor *sensor,
const struct bt_mesh_sensor_setting *setting,
struct bt_mesh_msg_ctx *ctx,
struct bt_mesh_sensor_value *rsp)
{
/** Get the current threshold in an application defined way and
* store it in rsp.
*/
get_threshold(rsp);
}
static int motion_threshold_set(struct bt_mesh_sensor_srv *srv,
struct bt_mesh_sensor *sensor,
const struct bt_mesh_sensor_setting *setting,
struct bt_mesh_msg_ctx *ctx,
const struct bt_mesh_sensor_value *value)
{
/** Store incoming threshold in application-defined way.
* Return error code to reject set.
*/
return set_threshold(value);
}
static const struct bt_mesh_sensor_setting settings[] = {
{
.type = &bt_mesh_sensor_motion_threshold,
.get = motion_threshold_get,
.set = motion_threshold_set,
}
};
static struct bt_mesh_sensor motion_sensor = {
.type = &bt_mesh_sensor_motion_sensed,
.get = get_motion,
.settings = {
.list = settings,
.count = ARRAY_SIZE(settings)
}
};
API documentation
include/bluetooth/mesh/sensor.h
subsys/bluetooth/mesh/sensor.c
- group bt_mesh_sensor
API for Bluetooth Mesh Sensors.
Defines
-
CONFIG_BT_MESH_SENSOR_CHANNEL_ENCODED_SIZE_MAX
-
BT_MESH_SENSOR_PERIOD_DIV_MAX
Largest period divisor value allowed.
-
BT_MESH_SENSOR_INTERVAL_MAX
Largest sensor interval allowed. The value is represented as 2 to the power of N milliseconds.
-
BT_MESH_SENSOR_CH_STR_LEN
String length for representing a single sensor channel.
-
BT_MESH_SENSOR_VALUE_IN_RANGE(_value, _start, _end)
Returns whether or not encoded sensor value _value is in the range [_start, _end], inclusive.
- Parameters:
_value – [in] The value to check.
_start – [in] Start point of the range to check, inclusive.
_end – [in] End point of the range to check, inclusive.
-
BT_MESH_SENSOR_TYPE_FLAG_SERIES
Flag indicating this sensor type has a series representation.
-
BT_MESH_SENSOR_TOLERANCE_ENCODE(_percent)
Encode a sensor tolerance percentage.
- Parameters:
_percent – [in] The sensor tolerance to encode, in percent.
Enums
-
enum bt_mesh_sensor_sampling
Sensor sampling type.
Represents the sampling function used to produce the presented sensor value.
Values:
-
enumerator BT_MESH_SENSOR_SAMPLING_UNSPECIFIED
The sampling function is unspecified
-
enumerator BT_MESH_SENSOR_SAMPLING_INSTANTANEOUS
The presented value is an instantaneous sample.
-
enumerator BT_MESH_SENSOR_SAMPLING_ARITHMETIC_MEAN
The presented value is the arithmetic mean of multiple samples.
-
enumerator BT_MESH_SENSOR_SAMPLING_RMS
The presented value is the root mean square of multiple samples.
-
enumerator BT_MESH_SENSOR_SAMPLING_MAXIMUM
The presented value is the maximum of multiple samples.
-
enumerator BT_MESH_SENSOR_SAMPLING_MINIMUM
The presented value is the minimum of multiple samples.
-
enumerator BT_MESH_SENSOR_SAMPLING_ACCUMULATED
The presented value is the accumulated moving average value of the samples. The updating frequency of the moving average should be indicated in bt_mesh_descriptor::update_interval. The total measurement period should be indicated in bt_mesh_descriptor::period.
-
enumerator BT_MESH_SENSOR_SAMPLING_COUNT
The presented value is a count of events in a specific measurement period. bt_mesh_descriptor::period should denote the measurement period, or left to 0 to indicate that the sample is a lifetime value.
-
enumerator BT_MESH_SENSOR_SAMPLING_UNSPECIFIED
-
enum bt_mesh_sensor_cadence
Sensor sampling cadence
Values:
-
enumerator BT_MESH_SENSOR_CADENCE_NORMAL
Normal sensor publish interval.
-
enumerator BT_MESH_SENSOR_CADENCE_FAST
Fast sensor publish interval.
-
enumerator BT_MESH_SENSOR_CADENCE_NORMAL
-
enum bt_mesh_sensor_value_status
Status of conversion from bt_mesh_sensor_value.
Values:
-
enumerator BT_MESH_SENSOR_VALUE_NUMBER
The encoded sensor value represents a number.
-
enumerator BT_MESH_SENSOR_VALUE_CONVERSION_ERROR
An error ocurred during conversion from the encoded sensor value.
-
enumerator BT_MESH_SENSOR_VALUE_CLAMPED
The encoded value could not fit in the target type and was clamped to the closest available value.
-
enumerator BT_MESH_SENSOR_VALUE_UNKNOWN
The encoded sensor value represents an unknown value.
-
enumerator BT_MESH_SENSOR_VALUE_INVALID
The encoded sensor value represents an invalid value.
-
enumerator BT_MESH_SENSOR_VALUE_MAX_OR_GREATER
The encoded sensor value represents a value greater than or equal to the format maximum.
-
enumerator BT_MESH_SENSOR_VALUE_MIN_OR_LESS
The encoded sensor value represents a value less than or equal to the format minimum.
-
enumerator BT_MESH_SENSOR_VALUE_TOTAL_DEVICE_LIFE
The encoded sensor value represents the total lifetime of the device.
-
enumerator BT_MESH_SENSOR_VALUE_NUMBER
Functions
-
int bt_mesh_sensor_value_compare(const struct bt_mesh_sensor_value *a, const struct bt_mesh_sensor_value *b)
Compare two bt_mesh_sensor_value instances.
- Parameters:
a – [in] The first value to compare.
b – [in] The second value to compare.
- Returns:
0 if
a
==b
, 1 ifa
>b
, -1 otherwise (including ifa
andb
are not comparable).
-
static inline bool bt_mesh_sensor_value_status_is_numeric(enum bt_mesh_sensor_value_status status)
Returns true if
status
is a value which can be represented by a number, meaning one ofBT_MESH_SENSOR_VALUE_NUMBER
,BT_MESH_SENSOR_VALUE_MIN_OR_LESS
,BT_MESH_SENSOR_VALUE_MAX_OR_GREATER
andBT_MESH_SENSOR_VALUE_CLAMPED
.- Parameters:
status – [in] The value to check.
- Returns:
true
ifstatus
is numeric,false
otherwise.
-
enum bt_mesh_sensor_value_status bt_mesh_sensor_value_to_float(const struct bt_mesh_sensor_value *sensor_val, float *val)
Convert a bt_mesh_sensor_value to a
float
.If this function returns a status for which bt_mesh_sensor_value_status_is_numeric returns false,
val
is not modified.- Parameters:
sensor_val – [in] The bt_mesh_sensor_value to convert.
val – [out] The resulting
float
.
- Returns:
The status of the conversion.
-
int bt_mesh_sensor_value_from_float(const struct bt_mesh_sensor_format *format, float val, struct bt_mesh_sensor_value *sensor_val)
Convert a
float
to a bt_mesh_sensor_value.If
val
has a value that cannot be represented by the format,sensor_val
will be set to the value clamped to the range supported by the format, and this function will return -ERANGE. This will clamp to “Greater than or equal to the maximum value” and “Less than or equal to the minimum value” if these are supported by the format.If this function returns an error code other than -ERANGE,
sensor_val
is not modified.- Parameters:
format – [in] Format to use when encoding the sensor value.
val – [in] The
float
to convert.sensor_val – [out] The resulting bt_mesh_sensor_value.
- Returns:
0 on success, (negative) error code otherwise.
-
enum bt_mesh_sensor_value_status bt_mesh_sensor_value_to_micro(const struct bt_mesh_sensor_value *sensor_val, int64_t *val)
Convert a bt_mesh_sensor_value instance to an integer in micro units.
If this function returns a status for which bt_mesh_sensor_value_status_is_numeric returns false,
val
is not modified.- Parameters:
sensor_val – [in] The bt_mesh_sensor_value to convert.
val – [out] The resulting integer.
- Returns:
The status of the conversion.
-
int bt_mesh_sensor_value_from_micro(const struct bt_mesh_sensor_format *format, int64_t val, struct bt_mesh_sensor_value *sensor_val)
Convert an integer in micro units to a bt_mesh_sensor_value.
If
val
has a value that cannot be represented by the format,sensor_val
will be set to the value clamped to the range supported by the format, and this function will return -ERANGE. This will clamp to “Greater than or equal to the maximum value” and “Less than or equal to the minimum value” if these are supported by the format.If this function returns an error code other than -ERANGE,
sensor_val
is not modified.- Parameters:
format – [in] Format to use when encoding the sensor value.
val – [in] The integer to convert.
sensor_val – [out] The resulting bt_mesh_sensor_value.
- Returns:
0 on success, (negative) error code otherwise.
-
enum bt_mesh_sensor_value_status bt_mesh_sensor_value_to_sensor_value(const struct bt_mesh_sensor_value *sensor_val, struct sensor_value *val)
Convert a bt_mesh_sensor_value instance to a
sensor_value
(include/zephyr/drivers/sensor.h).If this function returns a status for which bt_mesh_sensor_value_status_is_numeric returns false,
val
is not modified.- Parameters:
sensor_val – [in] The bt_mesh_sensor_value to convert.
val – [out] The resulting
sensor_value
.
- Returns:
The status of the conversion.
-
int bt_mesh_sensor_value_from_sensor_value(const struct bt_mesh_sensor_format *format, const struct sensor_value *val, struct bt_mesh_sensor_value *sensor_val)
Convert a
sensor_value
(include/zephyr/drivers/sensor.h) instance to a bt_mesh_sensor_value.If
val
has a value that cannot be represented by the format,sensor_val
will be set to the value clamped to the range supported by the format, and this function will return -ERANGE. This will clamp to “Greater than or equal to the maximum value” and “Less than or equal to the minimum value” if these are supported by the format.If this function returns an error code other than -ERANGE,
sensor_val
is not modified.- Parameters:
format – [in] Format to use when encoding the sensor value.
val – [in] The
sensor_value
to convert.sensor_val – [out] The resulting bt_mesh_sensor_value.
- Returns:
0 on success, (negative) error code otherwise.
-
enum bt_mesh_sensor_value_status bt_mesh_sensor_value_get_status(const struct bt_mesh_sensor_value *sensor_val)
Return a bt_mesh_sensor_value_status describing the value in a bt_mesh_sensor_value.
- Parameters:
sensor_val – [in] The value to return the status for.
- Returns:
The status describing the value.
-
int bt_mesh_sensor_value_from_special_status(const struct bt_mesh_sensor_format *format, enum bt_mesh_sensor_value_status status, struct bt_mesh_sensor_value *sensor_val)
Convert a bt_mesh_sensor_value_status value to a bt_mesh_sensor_value.
This is useful for creating a bt_mesh_sensor_value representing a special status value like
BT_MESH_SENSOR_VALUE_UNKNOWN
orBT_MESH_SENSOR_VALUE_TOTAL_DEVICE_LIFE
.This cannot be used to create a value representing
BT_MESH_SENSOR_VALUE_NUMBER
. Use one of bt_mesh_sensor_value_from_sensor_value, bt_mesh_sensor_value_from_micro or bt_mesh_sensor_value_from_float instead.Not all formats can represent all special status values. In the case where the supplied status value cannot be represented by the format, this function will return a (negative) error code.
- Parameters:
format – [in] Format to use when encoding the sensor value.
status – [in] The bt_mesh_sensor_value_status value to convert.
sensor_val – [out] The resulting bt_mesh_sensor_value on success. Unchanged otherwise.
- Returns:
0 on success, (negative) error code otherwise.
-
bool bt_mesh_sensor_value_in_column(const struct bt_mesh_sensor_value *value, const struct bt_mesh_sensor_column *col)
Check whether a single channel sensor value lies within a column.
- Parameters:
value – [in] Value to check. Only the first channel is considered.
col – [in] Sensor column.
- Returns:
true if the value belongs in the column, false otherwise.
-
int bt_mesh_sensor_ch_to_str(const struct bt_mesh_sensor_value *ch, char *str, size_t len)
Get a human readable representation of a single sensor channel.
Note
This prints float values internally for most formats, which requires
CONFIG_CBPRINTF_FP_SUPPORT
to be enabled.- Parameters:
ch – [in] Sensor channel to represent.
str – [out] String buffer to fill. Should be BT_MESH_SENSOR_CH_STR_LEN bytes long.
len – [in] Length of
str
buffer.
- Returns:
Number of bytes that should have been written if
str
is sufficiently large.
-
const char *bt_mesh_sensor_ch_str(const struct bt_mesh_sensor_value *ch)
Get a human readable representation of a single sensor channel.
Note
This prints float values internally for most formats, which requires
CONFIG_CBPRINTF_FP_SUPPORT
to be enabled.Note
This function is not thread safe.
- Parameters:
ch – [in] Sensor channel to represent.
- Returns:
A string representing the sensor channel.
-
const struct bt_mesh_sensor_type *bt_mesh_sensor_type_get(uint16_t id)
Get the sensor type associated with the given Device Property ID.
Only known sensor types from Sensor types will be available. Sensor types can be made known to the sensor module by enabling
CONFIG_BT_MESH_SENSOR_ALL_TYPES
or by referencing them in the application.- Parameters:
id – [in] A Device Property ID.
- Returns:
The associated sensor type, or NULL if the ID is unknown.
-
const struct bt_mesh_sensor_format *bt_mesh_sensor_column_format_get(const struct bt_mesh_sensor_type *type)
Get the format of the sensor column data.
- Parameters:
type – [in] Sensor type.
- Returns:
The sensor type’s sensor column format if series access is supported. Otherwise NULL.
-
struct bt_mesh_sensor_unit
- #include <sensor.h>
Unit for single sensor channel values.
-
struct bt_mesh_sensor_channel
- #include <sensor.h>
Single sensor channel
Public Members
-
const struct bt_mesh_sensor_format *format
Format for this sensor channel.
-
const struct bt_mesh_sensor_format *format
-
struct bt_mesh_sensor_type
- #include <sensor.h>
Sensor type. Should only be instantiated in sensor_types.c. See sensor_types.h for a list of all defined sensor types.
Public Members
-
uint16_t id
Device Property ID.
-
uint8_t flags
Flags,
See also
-
uint8_t channel_count
The number of channels supported by this type.
-
const struct bt_mesh_sensor_channel *channels
Array of channel descriptors.
All channels are mandatory and immutable.
-
uint16_t id
-
struct bt_mesh_sensor_value
- #include <sensor.h>
Sensor value type representing the value and format of a single channel of sensor data.
Public Members
-
const struct bt_mesh_sensor_format *format
The format the sensor value is encoded in.
-
uint8_t raw[0]
Raw encoded sensor value, in little endian order.
-
const struct bt_mesh_sensor_format *format
-
struct bt_mesh_sensor_descriptor
- #include <sensor.h>
Sensor descriptor representing various static metadata for the sensor.
Public Members
-
uint16_t positive
Encoded maximum positive measurement error.
Represents the magnitude of the maximum possible positive measurement error, in percent.
The value is encoded using the following formula:
encoded_value = (max_err_in_percent / 100) * 4095
A tolerance of 0 should be interpreted as “unspecified”.
-
uint16_t negative
Encoded maximum negative measurement error.
Represents the magnitude of the maximum possible negative measurement error, in percent.
The value is encoded using the following formula:
encoded_value = (max_err_in_percent / 100) * 4095
A tolerance of 0 should be interpreted as “unspecified”.
-
struct bt_mesh_sensor_descriptor.[anonymous] tolerance
Sensor measurement tolerance specification.
-
enum bt_mesh_sensor_sampling sampling_type
Sampling type for the sensor data.
-
uint64_t period
Measurement period for the samples, if applicable.
-
uint64_t update_interval
Update interval for the samples, if applicable.
-
uint16_t positive
-
struct bt_mesh_sensor_deltas
- #include <sensor.h>
Public Members
-
struct bt_mesh_sensor_value up
Minimal delta for a positive change.
-
struct bt_mesh_sensor_value down
Minimal delta for a negative change.
-
struct bt_mesh_sensor_value up
-
struct bt_mesh_sensor_threshold
- #include <sensor.h>
Sensor thresholds for publishing.
Public Members
-
struct bt_mesh_sensor_deltas deltas
Delta threshold values.
Denotes the minimal sensor value change that should cause the sensor to publish its value.
-
enum bt_mesh_sensor_cadence cadence
Cadence when the sensor value is inside the range.
If the cadence is fast when the value is inside the range, it is normal when it is outside the range. If the cadence is normal when the value is inside the range, it is fast outside the range.
-
struct bt_mesh_sensor_value low
Lower boundary for the range based sensor cadence threshold.
-
struct bt_mesh_sensor_value high
Upper boundary for the range based sensor cadence threshold.
-
struct bt_mesh_sensor_threshold.[anonymous] range
Range based threshold values.
Denotes the value range in which the sensor should be in fast cadence mode.
-
struct bt_mesh_sensor_deltas deltas
-
struct bt_mesh_sensor_column
- #include <sensor.h>
Single sensor series data column.
The series data columns represent a range for specific measurement values, inside which a set of sensor measurements were made. The range is interpreted as a half-open interval (i.e. start <= value < start + width).
Public Members
-
struct bt_mesh_sensor_value start
Start of the column (inclusive).
-
struct bt_mesh_sensor_value width
Width of the column.
-
struct bt_mesh_sensor_value start
-
struct bt_mesh_sensor_format_cb
- #include <sensor.h>
Sensor format callbacks.
(For internal use, applications should use the conversion functions provided in sensor.h instead.)
Public Members
-
bool (*const delta_check)(const struct bt_mesh_sensor_value *current, const struct bt_mesh_sensor_value *previous, const struct bt_mesh_sensor_deltas *delta)
Perform a delta check between two bt_mesh_sensor_value instances.
current
andprevious
must have the same format.- Param current:
[in] The current value.
- Param previous:
[in] The previous sensor value to compare against.
- Param delta:
[in] The delta to use when checking.
- Return:
true
if the difference betweencurrent
andprevious
is bigger than the relevant delta specified indelta
,false
otherwise.
-
int (*const compare)(const struct bt_mesh_sensor_value *op1, const struct bt_mesh_sensor_value *op2)
Compare two bt_mesh_sensor_value instances.
op1
andop1
must have the same format.- Param op1:
[in] The first value to compare.
- Param op2:
[in] The second value to compare.
- Return:
0 if
op1
==op2
, 1 ifop1
>op2
, -1 otherwise (including ifop1
andop2
are not comparable).
-
enum bt_mesh_sensor_value_status (*const to_micro)(const struct bt_mesh_sensor_value *sensor_val, int64_t *val)
Convert a bt_mesh_sensor_value instance to an integer in micro units.
If this function returns a status for which bt_mesh_sensor_value_status_is_numeric returns false,
val
is not modified.- Param sensor_val:
[in] The bt_mesh_sensor_value to convert.
- Param val:
[out] The resulting integer.
- Return:
The status of the conversion.
-
int (*const from_micro)(const struct bt_mesh_sensor_format *format, int64_t val, struct bt_mesh_sensor_value *sensor_val)
Convert an integer in micro units to a bt_mesh_sensor_value.
If
val
has a value that cannot be represented by the format,sensor_val
will be set to the value clamped to the range supported by the format, and this function will return -ERANGE. This will clamp to “Greater than or equal to the maximum value” and “Less than or equal to the minimum value” if these are supported by the format.If this function returns an error code other than -ERANGE,
sensor_val
is not modified.- Param format:
[in] Format to use when encoding the sensor value.
- Param val:
[in] The integer to convert.
- Param sensor_val:
[out] The resulting bt_mesh_sensor_value.
- Return:
0 on success, (negative) error code otherwise.
-
enum bt_mesh_sensor_value_status (*const to_float)(const struct bt_mesh_sensor_value *sensor_val, float *val)
Convert a bt_mesh_sensor_value to a
float
.If this function returns a status for which bt_mesh_sensor_value_status_is_numeric returns false,
val
is not modified.- Param sensor_val:
[in] The bt_mesh_sensor_value to convert.
- Param val:
[out] The resulting
float
.- Return:
The status of the conversion.
-
int (*const from_float)(const struct bt_mesh_sensor_format *format, float val, struct bt_mesh_sensor_value *sensor_val)
Convert a
float
to a bt_mesh_sensor_value.If
val
has a value that cannot be represented by the format,sensor_val
will be set to the value clamped to the range supported by the format, and this function will return -ERANGE. This will clamp to “Greater than or equal to the maximum value” and “Less than or equal to the minimum value” if these are supported by the format.If this function returns an error code other than -ERANGE,
sensor_val
is not modified.- Param format:
[in] Format to use when encoding the sensor value.
- Param val:
[in] The
float
to convert.- Param sensor_val:
[out] The resulting bt_mesh_sensor_value.
- Return:
0 on success, (negative) error code otherwise.
-
int (*const from_special_status)(const struct bt_mesh_sensor_format *format, enum bt_mesh_sensor_value_status status, struct bt_mesh_sensor_value *sensor_val)
Convert a special bt_mesh_sensor_value_status value to a bt_mesh_sensor_value.
- Param format:
[in] Format to use when encoding the sensor value.
- Param status:
[in] The bt_mesh_sensor_value_status to convert.
- Param sensor_val:
[out] The resulting bt_mesh_sensor_value on success. Undefined otherwise.
- Return:
0 on success, (negative) error code otherwise.
-
int (*const to_string)(const struct bt_mesh_sensor_value *sensor_val, char *str, size_t len)
Get a human readable representation of a bt_mesh_sensor_value.
- Param sensor_val:
[in] Sensor value to represent.
- Param str:
[out] String buffer to fill. Should be BT_MESH_SENSOR_CH_STR_LEN bytes long.
- Param len:
[in] Length of
str
buffer.- Return:
The number of characters that would have been writen if
len
had been big enough, or (negative) error code on error.
-
bool (*const value_in_column)(const struct bt_mesh_sensor_value *sensor_val, const struct bt_mesh_sensor_column *col)
Check if a bt_mesh_sensor_value lies within a bt_mesh_sensor_column.
sensor_val
,col->start
andcol->width
must all have the same format.If
sensor_val
,col->start
orcol->width
represent a non-numeric value, this will returnfalse
.A value is considered to be in a column if
start <= value <= start + width
where start is the value represented by
col->start
, value is the value represented bysensor_val
, and width is the value represented bycol->width
.- Param sensor_val:
[in] The bt_mesh_sensor_value to check.
- Param col:
[in] The bt_mesh_sensor_column to check against.
- Return:
true
ifsensor_val
,col->start
andcol->width
represent numeric values andsensor_val
is inside the range specified bycol
, inclusive.false
otherwise.
-
bool (*const delta_check)(const struct bt_mesh_sensor_value *current, const struct bt_mesh_sensor_value *previous, const struct bt_mesh_sensor_deltas *delta)
-
struct bt_mesh_sensor_format
- #include <sensor.h>
Sensor channel value format.
Public Members
-
struct bt_mesh_sensor_format_cb *cb
Callbacks used for this format.
(For internal use. Applications should use the conversion functions in sensor.h)
-
void *user_data
User data pointer. Used internally by the sensor types.
-
size_t size
Size of the encoded data in bytes.
-
struct bt_mesh_sensor_format_cb *cb
-
struct bt_mesh_sensor_setting
- #include <sensor.h>
Single sensor setting.
Public Members
-
const struct bt_mesh_sensor_type *type
Sensor type of this setting.
-
void (*get)(struct bt_mesh_sensor_srv *srv, struct bt_mesh_sensor *sensor, const struct bt_mesh_sensor_setting *setting, struct bt_mesh_msg_ctx *ctx, struct bt_mesh_sensor_value *rsp)
Getter for this sensor setting.
Note
This handler is mandatory.
- Param srv:
[in] Sensor server instance associated with this setting.
- Param sensor:
[in] Sensor this setting belongs to.
- Param setting:
[in] Pointer to this setting structure.
- Param ctx:
[in] Context parameters for the packet this call originated from, or NULL if this call wasn’t triggered by a packet.
- Param rsp:
[out] Response buffer for the setting value. Points to an array with the number of channels specified by the setting sensor type. All channels must be filled.
-
int (*set)(struct bt_mesh_sensor_srv *srv, struct bt_mesh_sensor *sensor, const struct bt_mesh_sensor_setting *setting, struct bt_mesh_msg_ctx *ctx, const struct bt_mesh_sensor_value *value)
Setter for this sensor setting.
Should only be specified for writable sensor settings.
- Param srv:
[in] Sensor server instance associated with this setting.
- Param sensor:
[in] Sensor this setting belongs to.
- Param setting:
[in] Pointer to this setting structure.
- Param ctx:
[in] Context parameters for the packet this call originated from, or NULL if this call wasn’t triggered by a packet.
- Param value:
[in] New setting value. Contains the number of channels specified by the setting sensor type.
- Return:
0 on success, or (negative) error code otherwise.
-
const struct bt_mesh_sensor_type *type
-
struct bt_mesh_sensor_series
- #include <sensor.h>
Sensor series specification.
Public Members
-
const struct bt_mesh_sensor_column *columns
Pointer to the list of columns.
The columns may overlap, but the start value of each column must be unique. The list of columns do not have to cover the entire valid range, and values that don’t fit in any of the columns should be ignored. If columns overlap, samples must be present in all columns they fall into. The columns may come in any order.
This list is not used for sensor types with one or two channels.
-
uint32_t column_count
Number of columns.
-
int (*get)(struct bt_mesh_sensor_srv *srv, struct bt_mesh_sensor *sensor, struct bt_mesh_msg_ctx *ctx, uint32_t column_index, struct bt_mesh_sensor_value *value)
Getter for the series values.
Should return the historical data for the latest sensor readings in the given column.
- Param srv:
[in] Sensor server associated with sensor instance.
- Param sensor:
[in] Sensor pointer.
- Param ctx:
[in] Message context pointer, or NULL if this call didn’t originate from a mesh message.
- Param column_index:
[in] The index of the requested sensor column. Index into the
columns
array for sensors with more than two channels.- Param value:
[out] Sensor value response buffer. Holds the number of channels indicated by the sensor type. All channels must be filled.
- Return:
0 on success, or (negative) error code otherwise.
-
const struct bt_mesh_sensor_column *columns
-
struct bt_mesh_sensor
- #include <sensor.h>
Sensor instance.
Public Members
-
const struct bt_mesh_sensor_type *type
Sensor type.
Must be one of the specification defined types listed in Sensor types.
-
const struct bt_mesh_sensor_descriptor *descriptor
Optional sensor descriptor.
-
const struct bt_mesh_sensor_setting *list
Static array of sensor settings
-
size_t count
Number of sensor settings.
-
const struct bt_mesh_sensor.[anonymous] settings
Sensor settings access specification.
-
const struct bt_mesh_sensor_series series
Sensor series specification.
Only sensors who have a non-zero column-count and a defined series getter will accept series messages. Sensors with more than two channels also require a non-empty list of columns.
-
int (*const get)(struct bt_mesh_sensor_srv *srv, struct bt_mesh_sensor *sensor, struct bt_mesh_msg_ctx *ctx, struct bt_mesh_sensor_value *rsp)
Getter function for the sensor value.
- Param srv:
[in] Sensor server associated with sensor instance.
- Param sensor:
[in] Sensor instance.
- Param ctx:
[in] Message context, or NULL if the call wasn’t triggered by a mesh message.
- Param rsp:
[out] Value response buffer. Fits the number of channels specified by the sensor type. All channels must be filled.
- Return:
0 on success, or (negative) error code otherwise.
-
struct bt_mesh_sensor_threshold threshold
Sensor threshold specification.
-
sys_snode_t node
Linked list node.
-
struct bt_mesh_sensor_value prev
The previously published sensor value.
-
uint16_t seq
Sequence number of the previous publication.
-
uint8_t min_int
Minimum possible interval for fast cadence value publishing. The value is represented as 2 to the power of N milliseconds.
See also
-
uint8_t pub_div
Fast period divisor used when publishing with fast cadence.
-
uint8_t fast_pub
Flag indicating whether the sensor is in fast cadence mode.
-
uint8_t configured
Flag indicating whether the sensor cadence state has been configured.
-
const struct bt_mesh_sensor_type *type
-
CONFIG_BT_MESH_SENSOR_CHANNEL_ENCODED_SIZE_MAX