This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Setting up a Bluetooth mesh sensor server values

There's a Bluetooth mesh sensor server, which realize, for example:

  • present ambient temperature property and
  • desired ambient temperature property.

A Bluetooth mesh sensor client can read its temperature from sensor server requesting data using bt_mesh_sensor_cli_get function or it can listen to messages, which were sent using bt_mesh_sensor_srv_pub function. But how can the Buetooth mesh sensor client set up the desired temperature in the Bluetooth mesh sensor server? There's no a function kinda bt_mesh_sensor_cli_set. Should I use bt_mesh_sensor_cli_setting_set? And in this case I have to be able to read the desired value, using bt_mesh_sensor_cli_setting_get, as I understand. In those functions, bt_mesh_sensor_cli_setting_get and bt_mesh_sensor_cli_setting_set, const struct bt_mesh_sensor_type *sensor has to be a pointer to a bt_mesh_sensor_desired_amb_temp, but I don't see which value I should pass as a const struct bt_mesh_sensor_type *setting. Could you explain, please, how a sensor client can set up a sensor server value by the example of the desired ambient temperature property?

If it's worth to mention, I use nRF52840 DK with nRF Connect SDK 1.4.1.

Thank you in advance.

Parents
  • Hi Roman, 
    I would need to check with the mesh team to give a concrete answer. But from my understanding, you would need to add a sensor type of desired_amb_temp, as defined in sensor_type.c:

    SENSOR_TYPE(desired_amb_temp) = {
    	.id = BT_MESH_PROP_ID_DESIRED_AMB_TEMP,
    	CHANNELS(CHANNEL("Desired ambient temperature", temp_8)),

    into your sensor structure like what we have in the sensor_server example: 
    static struct bt_mesh_sensor *const sensors[] = {
    	&chip_temp,
    	&rel_chip_temp_runtime,
    	&presence_sensor,
    	&time_since_presence_detected,
    };

    After that you can call bt_mesh_sensor_cli_set() to set the desired ambient temp. 

  • Thanks for your answer!

    Just a notice: I made a typo in my question, when I wrote "In those functions, bt_mesh_sensor_cli_setting_get and bt_mesh_sensor_cli_set, ...", and at the same time in one of the previous sentences I wrote that there's no such function bt_mesh_sensor_cli_set. Certainly, I meant "In those functions, bt_mesh_sensor_cli_setting_get and bt_mesh_sensor_cli_setting_set, ...". Now I edited the question.

    I understood the part of code, which you described. I have something like it, where I merely hardcoded the desired ambient temperature value (22.0) to simplify the example:

    static int desired_amb_temp_get(struct bt_mesh_sensor *sensor, struct bt_mesh_msg_ctx *ctx, struct sensor_value *rsp)
    {
        rsp->val1 = 22;
        rsp->val2 = 0;
    
        return 0;
    }
    
    static struct bt_mesh_sensor present_amb_temp = {
        .type = &bt_mesh_sensor_present_amb_temp,
        .get = temperature_sensor_get,
    };
    
    static struct bt_mesh_sensor desired_amb_temp = {
        .type = &bt_mesh_sensor_desired_amb_temp,
        .get = desired_amb_temp_get,
    };
    
    static struct bt_mesh_sensor *const sensors[] = {
        &present_amb_temp,
        &desired_amb_temp,
    };
    
    static struct bt_mesh_sensor_srv sensor_srv = BT_MESH_SENSOR_SRV_INIT(sensors, ARRAY_SIZE(sensors));


    And everything is okay with getter callbacks. But the problem is that there's no such setter function bt_mesh_sensor_cli_set() to set the desired ambient temperature. And even the Bluetooth mesh specification doesn't specify a Sensor Set message in 4.2 section (Sensor messages) of Mesh Model. So it's implied that the Sensor Server values have to be set up in another way. Thus, 4.1.2 Sensor Setting describes an example of setting up a sensitivity for an occupancy sensor. But in this example I can't understand what I should to provide as Sensor Setting Property ID and the specification also says nothing about it, just it has a link to another section, that sections has a link to www.bluetooth.com/.../characteristics with redirection to www.bluetooth.com/.../. And even in the 16-bit UUID Numbers Document in section GATT Characteristic and Object Type there's no occupancy and sensitivity, which were mentioned in the example in the specification. That's why I don't know how to use the functions bt_mesh_sensor_cli_setting_get() and bt_mesh_sensor_cli_setting_set(). Can you explain to me how to use these functions, which argument I should pass as const struct bt_mesh_sensor_type *setting and how a Sensor Client has to adjust the desired ambient temperature value in a Sensor Server?

  • Hi Roman, 

    We don't really have a ready-made example to show you how bt_mesh_sensor_cli_setting_set() is to be used. 
    So we will need to interpret the spec to get what we need to do. 
    I had a discussion with our mesh team member on this regard. He pointed that at 4.1.2 the spec should have pointed to Mesh Device Properties document instead. 
    In that document you can find the Desired Ambient Temperature properties is defined as "Temperature 8" characteristic and has the property ID = 0x0071. ( you can find explanation on Temperature 8 in this document)

    I quoted here the reply from our mesh team member: 

    Both documents describe a representation of the sensor (how to read and how to configure) within the model approach in the Bluetooth Mesh network. The exact algorithm of sensor work is beyond spec.  

    There are sensor samples here `../samples/bluetooth/mesh/`  However, I'm not sure they use setting-related commands. 

    For me the algorithm of sensor settings usage is:

    1. Read out the list of possible sensor settings by `Sensor Settings Get` — `Sensor Settings Status`.
    2. Chose parameters which you want to configure and send it to a server by 'Sensor Setting Set'.
    3. Control configuration from time to time sending `Sensor Setting Get`  or configure periodic publishing of `Sensor Setting Status`.


    Another source of reference you may want to have a look is to our nRF5 Mesh SDK (instead of NCS). In the sensor client example there, we do send a sensor_client_settings_get(). By studying the format of this package, you can apply it to the call in NCS. 

  • Thank you! Now I understood the way how to get and set sensor settings. Before I confused that the bt_mesh_sensor_desired_amb_temp should be not as a separate sensor, and it should be in the settings' list of the bt_mesh_sensor_present_amb_temp sensor.

    And now the code on the server side looks kinda like this:

    struct sensor_value desired_amb_temp = {.val1 = 22, .val2 = 000000};
    
    void desired_amb_temp_get(struct bt_mesh_sensor *sensor,
                              const struct bt_mesh_sensor_setting *setting,
                              struct bt_mesh_msg_ctx *ctx,
                              struct sensor_value *rsp)
    {
        *rsp = desired_amb_temp;
    }
    
    int desired_amb_temp_set(struct bt_mesh_sensor *sensor,
                             const struct bt_mesh_sensor_setting *setting,
                             struct bt_mesh_msg_ctx *ctx,
                             const struct sensor_value *value)
    {
        desired_amb_temp = *value;
    
        return 0;
    }
    
    const struct bt_mesh_sensor_setting setting_list[] = {
        {
            .type = &bt_mesh_sensor_desired_amb_temp,
            .get = &desired_amb_temp_get,
            .set = &desired_amb_temp_set,
        },
    };
    
    static struct bt_mesh_sensor present_amb_temp = {
        .type = &bt_mesh_sensor_present_amb_temp,
        .get = temperature_sensor_get,
        .settings = {
            .list = setting_list,
            .count = ARRAY_SIZE(setting_list),
        },
    };



    And as an example, on the client side I call something like this:

    To get all settings for the particular sensor bt_mesh_sensor_present_amb_temp:
    bt_mesh_sensor_cli_settings_get(&sensor_cli, NULL, &bt_mesh_sensor_present_amb_temp, NULL, NULL);


    To get a value of bt_mesh_sensor_desired_amb_temp setting of the sensor bt_mesh_sensor_present_amb_temp:
    bt_mesh_sensor_cli_setting_get(&sensor_cli, NULL, &bt_mesh_sensor_present_amb_temp, &bt_mesh_sensor_desired_amb_temp, NULL);


    To set a desired value to the setting bt_mesh_sensor_desired_amb_temp of the sensor bt_mesh_sensor_present_amb_temp:
    struct sensor_value value = {.val1 = 33, .val2 = 500000};
    bt_mesh_sensor_cli_setting_set(&sensor_cli, NULL, &bt_mesh_sensor_present_amb_temp, &bt_mesh_sensor_desired_amb_temp, &value, NULL);

Reply
  • Thank you! Now I understood the way how to get and set sensor settings. Before I confused that the bt_mesh_sensor_desired_amb_temp should be not as a separate sensor, and it should be in the settings' list of the bt_mesh_sensor_present_amb_temp sensor.

    And now the code on the server side looks kinda like this:

    struct sensor_value desired_amb_temp = {.val1 = 22, .val2 = 000000};
    
    void desired_amb_temp_get(struct bt_mesh_sensor *sensor,
                              const struct bt_mesh_sensor_setting *setting,
                              struct bt_mesh_msg_ctx *ctx,
                              struct sensor_value *rsp)
    {
        *rsp = desired_amb_temp;
    }
    
    int desired_amb_temp_set(struct bt_mesh_sensor *sensor,
                             const struct bt_mesh_sensor_setting *setting,
                             struct bt_mesh_msg_ctx *ctx,
                             const struct sensor_value *value)
    {
        desired_amb_temp = *value;
    
        return 0;
    }
    
    const struct bt_mesh_sensor_setting setting_list[] = {
        {
            .type = &bt_mesh_sensor_desired_amb_temp,
            .get = &desired_amb_temp_get,
            .set = &desired_amb_temp_set,
        },
    };
    
    static struct bt_mesh_sensor present_amb_temp = {
        .type = &bt_mesh_sensor_present_amb_temp,
        .get = temperature_sensor_get,
        .settings = {
            .list = setting_list,
            .count = ARRAY_SIZE(setting_list),
        },
    };



    And as an example, on the client side I call something like this:

    To get all settings for the particular sensor bt_mesh_sensor_present_amb_temp:
    bt_mesh_sensor_cli_settings_get(&sensor_cli, NULL, &bt_mesh_sensor_present_amb_temp, NULL, NULL);


    To get a value of bt_mesh_sensor_desired_amb_temp setting of the sensor bt_mesh_sensor_present_amb_temp:
    bt_mesh_sensor_cli_setting_get(&sensor_cli, NULL, &bt_mesh_sensor_present_amb_temp, &bt_mesh_sensor_desired_amb_temp, NULL);


    To set a desired value to the setting bt_mesh_sensor_desired_amb_temp of the sensor bt_mesh_sensor_present_amb_temp:
    struct sensor_value value = {.val1 = 33, .val2 = 500000};
    bt_mesh_sensor_cli_setting_set(&sensor_cli, NULL, &bt_mesh_sensor_present_amb_temp, &bt_mesh_sensor_desired_amb_temp, &value, NULL);

Children
No Data
Related