airQualitySensor is not a valid value - Cannot parse notification data

Hi,

I am trying to make C code for an ESP32 which contains an air quality sensor. I am trying to use the capability airQualitySensor.

My st-device-sdk-c-ref repo is in master branch:
6ec0fe5 (HEAD → master, origin/master, origin/HEAD) doc: getting_started: update smartthings docs link

The iot-core library is in master branch as well:
03bdb61 (HEAD, origin/master_rel_1_7_5) Update CHANGELOG.md until v1.7.5

The error only happens on the air quality sensor, since the other capabilities are ok and are displayed on my Smartthings APP. Here is a good example:
[IoT]: st_cap_send_attr(613) > publish event, topic : /v1/deviceEvents/d559d1a6-d73f-49a0-b5f1-5d9b28c92d41, payload :
{“deviceEvents”:[{“component”:“main”,“capability”:“relativeHumidityMeasurement”,“attribute”:“humidity”,“value”:48.65,“unit”:“%”,“providerData”:{“sequenceNumber”:5,“timestamp”:“1675893682182”}}]}e[0m

Here is the example with the airQualitySensor and the error:
[IoT]: st_cap_send_attr(613) > publish event, topic : /v1/deviceEvents/d559d1a6-d73f-49a0-b5f1-5d9b28c92d41, payload :
{“deviceEvents”:[{“component”:“main”,“capability”:“airQualitySensor”,“attribute”:“airQuality”,“value”:60,“unit”:“I”,“providerData”:{“sequenceNumber”:13,“timestamp”:“1675893802509”}}]}e[0m

[IoT]: _iot_parse_noti_data(649) > payload : {“error”:{“requestId”:“ca56f6ef-7e40-4583-86df-0c121345db5b”,“error”:{“code”:“ConstraintViolationError”,“message”:“The request is malformed.”,“details”:[{“code”:“NotValidValue”,“target”:“deviceEvents[0].capability”,“message”:“airQualitySensor is not a valid value.”}]}},“target”:“d559d1a6-d73f-49a0-b5f1-5d9b28c92d41”,“event”:“error”,“source”:“device-backend”,“category”:“platform”}e[0m

My device config file has the following content:
{
“mnmn”: ,
“vid”: ,
“version”: “0.0.1”,
“type”: “profile”,
“dashboard”: {
“states”: ,
“actions”: [
{
“component”: “main”,
“capability”: “switch”,
“version”: 1,
“idx”: 0,
“group”: “main”
}
]
},
“detailView”: [
{
“component”: “main”,
“capability”: “healthCheck”,
“version”: 1,
“values”: ,
“patch”:
},
{
“component”: “main”,
“capability”: “temperatureMeasurement”,
“version”: 1,
“values”: ,
“patch”:
},
{
“component”: “main”,
“capability”: “relativeHumidityMeasurement”,
“version”: 1,
“values”: ,
“patch”:
},
{
“component”: “main”,
“capability”: “airQualitySensor”,
“version”: 1,
“values”: ,
“patch”:
},
{
“component”: “main”,
“capability”: “switch”,
“version”: 1,
“values”: ,
“patch”:
},
{
“component”: “main”,
“capability”: “firmwareUpdate”,
“version”: 1,
“values”: ,
“patch”:
}
],
“automation”: {
“conditions”: [
{
“component”: “main”,
“capability”: “healthCheck”,
“version”: 1,
“values”: ,
“patch”: ,
“exclusion”:
},
{
“component”: “main”,
“capability”: “temperatureMeasurement”,
“version”: 1,
“values”: ,
“patch”: ,
“exclusion”:
},
{
“component”: “main”,
“capability”: “relativeHumidityMeasurement”,
“version”: 1,
“values”: ,
“patch”: ,
“exclusion”:
},
{
“component”: “main”,
“capability”: “airQualitySensor”,
“version”: 1,
“values”: ,
“patch”: ,
“exclusion”:
},
{
“component”: “main”,
“capability”: “switch”,
“version”: 1,
“values”: ,
“patch”: ,
“exclusion”:
},
{
“component”: “main”,
“capability”: “firmwareUpdate”,
“version”: 1,
“values”: ,
“patch”: ,
“exclusion”:
}
],
“actions”: [
{
“component”: “main”,
“capability”: “healthCheck”,
“version”: 1,
“values”: ,
“patch”: ,
“exclusion”:
},
{
“component”: “main”,
“capability”: “switch”,
“version”: 1,
“values”: ,
“patch”: ,
“exclusion”:
},
{
“component”: “main”,
“capability”: “firmwareUpdate”,
“version”: 1,
“values”: ,
“patch”: ,
“exclusion”:
}
]
},
“migration”: true
}

Dear ST developers, may I please have some help on finding the cause of this error please ?

Hi, @picam-jmartins!

Ok, I have two questions about this:

  1. The configuration you shared is from the device profile, right? Did you remove the VID and MNMN for this post?
    Can you share the device profile ID of the one you created in the Developer Workspace (and the Direct-Connected project), please?

  2. The capability “airQualitySensor” only accepts the units “CAQI” and “IAQ”, so this could be rejected because of that.
    But, when you get an error like this from the API, it generally means you don’t have that capability in your device profile. Does this capability appear in the API (device list) and the ST app?

Hi,

  1. Yes. that’s my device profile.
    VID and MNMN were removed. Here they are:
    “mnmn”: “0AL0”,
    “vid”: “ST_e673c5d1-955f-493e-b1c1-5f428a8981f0”,

  2. The units are what it’s defined in the iot caps helper file for air quality sensor. I did not change it:
    .id = “airQualitySensor”,
    .attr_airQuality = {
    .name = “airQuality”,
    .property = ATTR_SET_VALUE_MIN | ATTR_SET_VALUE_MAX | ATTR_SET_VALUE_REQUIRED,
    .valueType = VALUE_TYPE_INTEGER,
    .units = {“CAQI”},
    .unit_CAQI = “CAQI”,
    .min = 0,
    .max = 100,
    },

  3. The capability appears on the device list and also on the ST app:

However, I have to admit that when I created the project initially it did not have this airQualitySensor capability. I add it later. Could it be that I have to remove the device from test and put it back to test ?

Hi,

I have removed my device under test and took it from test deployment.
I then add a new device and re-deployed to test.

The error is the same. I cannot publish air quality data, but can publish temperature and humidity.

Hi, @picam-jmartins

Sorry for the delay.
So, you included this capability using the capability helper.
Can you share a code snippet on how you’re calling this command that throws the error, please?

Hi,

This is how I initialize the capability:

    /* Initialize the air quality measurement capability */
    cap_airQualitySensor_data = caps_airQualitySensor_initialize(iot_ctx, "main", NULL, NULL);
    if (cap_airQualitySensor_data)
    {
        /* These are the init values */
        cap_airQualitySensor_data->set_airQuality_value(cap_airQualitySensor_data, 0);
        cap_airQualitySensor_data->set_airQuality_unit(cap_airQualitySensor_data, "CAQI");
    }

This is how I set a value to the capability:

cap_airQualitySensor_data->set_airQuality_value(cap_airQualitySensor_data, VALUE);

This is how I send the capability’s value to ST:

cap_airQualitySensor_data->attr_airQuality_send(cap_airQualitySensor_data);

Here is the definition of the callback registered in the send function:

static void caps_airQualitySensor_attr_airQuality_send(caps_airQualitySensor_data_t *caps_data)
{
    int sequence_no = -1;

    if (!caps_data || !caps_data->handle)
    {
        ESP_LOGE(TAG, "fail to get handle");
        return;
    }

    ESP_LOGI(TAG, "About to send IAQ Data: val = %d, unit = %s", caps_data->airQuality_value, caps_data->airQuality_unit);
    ST_CAP_SEND_ATTR_NUMBER(caps_data->handle,
            (char *)caps_helper_airQualitySensor.attr_airQuality.name,
            caps_data->airQuality_value,
            caps_data->airQuality_unit,
            NULL,
            sequence_no);

    if (sequence_no < 0)
    {
        ESP_LOGE(TAG, "fail to send airQuality value");
    }
    else
    {
        ESP_LOGI(TAG, "Sequence number return : %d", sequence_no);
    }
}

The log shows that the send was successful has the sequence number is positive:

[CAPS_AQI]: About to send IAQ Data: val = 57, unit = CAQI
[IoT]: st_cap_send_attr(613) > publish event, topic : /v1/deviceEvents/d559d1a6-d73f-49a0-b5f1-5d9b28c92d41, payload :{"deviceEvents":[{"component":"main","capability":"airQualitySensor","attribute":"airQuality","value":57,"unit":"CAQI","providerData":{"sequenceNumber":6,"timestamp":"1675893682236"}}]}
[CAPS_AQI]: Sequence number return : 6

But the response from the server is the error:

[IoT]: _iot_parse_noti_data(649) > payload : {"error":{"requestId":"19fe5868-4dd0-490d-878c-0405acba0b79","error":{"code":"ConstraintViolationError","message":"The request is malformed.","details":[{"code":"NotValidValue","target":"deviceEvents[0].capability","message":"airQualitySensor is not a valid value."}]}},"target":"d559d1a6-d73f-49a0-b5f1-5d9b28c92d41","event":"error","source":"device-backend","category":"platform"}

Hi @nayelyz ,

Just wondering if you have any update on this issue.
I am wondering if this is an issue on the backend, given that the error says:
“event”:“error”,“source”:“device-backend”,“category”:“platform”

@picam-jmartins
Hello, looks like there is no “airQualitySensor” capability under “main” component. Could you check the capability is under “main” component in the device profile?

Looks like it’s in “AirQuality” component.

Hi,

Yes… it’s not in main component. Should it be ?
(When I originally posted this issue this capability was in main component)

So, you mean that I cannot send a sensor value if the capability is not on the main component ?
How do I send a sensor value to a different component ?

That is the confusing thing. In your first post the device config suggested the capability was in the ‘main’ component, so the error was baffling.

In a subsequent post a screenshot shows it is in a different component, in which case the error seems quite reasonable.

You provided code earlier that includes …

caps_airQualitySensor_initialize(iot_ctx, "main", NULL, NULL);

I’ve not played with this sort of integration but the second parameter there defines the name of the component so I guess that is how you specify it.

I made a mistake while posting my logs as I was trying many different things. My apologies.

After changing the initialize from component “main” to “AirQuality” it started to work. All good now.

What I think it happened was that I added the air quality sensor capability AFTER I deployed the project to test. Maybe this was the problem after all.

When I took the project out of test, destroyed the device and created a new one, I made the mistake of moving the air quality capability out of the “main” component and into “AirQuality”. That’s why after creating a new device this was still not working.

I guess that the summary is that when a new capability is added, the device should be deleted and re-deployed to test.

Thank you for all your support.