diff --git a/components/esp_rainmaker/include/esp_rmaker_core.h b/components/esp_rainmaker/include/esp_rmaker_core.h index 9dbdbae..ad83011 100644 --- a/components/esp_rainmaker/include/esp_rmaker_core.h +++ b/components/esp_rainmaker/include/esp_rmaker_core.h @@ -63,6 +63,8 @@ typedef struct { char *fw_version; /** Model (Optional). If not set, PROJECT_NAME is used as default (recommended)*/ char *model; + /** Subtype (Optional). */ + char *subtype; } esp_rmaker_node_info_t; /** ESP RainMaker Configuration */ @@ -430,10 +432,11 @@ esp_err_t esp_rmaker_node_add_attribute(const esp_rmaker_node_t *node, const cha */ esp_err_t esp_rmaker_node_add_fw_version(const esp_rmaker_node_t *node, const char *fw_version); -/** Add model for a node (Not recommended) +/** Add model for a node * * Model is set internally to the project name. This API can be used to - * override that name. + * override that name, now that a new field "project" has also been added + * internally to the node info. * * @param node Node handle. * @param[in] model New model string. @@ -443,6 +446,16 @@ esp_err_t esp_rmaker_node_add_fw_version(const esp_rmaker_node_t *node, const ch */ esp_err_t esp_rmaker_node_add_model(const esp_rmaker_node_t *node, const char *model); +/** Add subtype for a node + * + * @param node Node handle. + * @param[in] subtype Subtype string. + * + * @return ESP_OK on success. + * @return error in case of failure. + */ +esp_err_t esp_rmaker_node_add_subtype(const esp_rmaker_node_t *node, const char *subtype); + /** * Create a Device * @@ -572,6 +585,18 @@ esp_err_t esp_rmaker_device_add_attribute(const esp_rmaker_device_t *device, con */ esp_err_t esp_rmaker_device_add_subtype(const esp_rmaker_device_t *device, const char *subtype); +/** Add a Device model + * + * This would primarily be used by the phone apps to render different icons for the same device type. + * + * @param[in] device Device handle. + * @param[in] model String describing the model. + * + * @return ESP_OK if the model was added successfully. + * @return error in case of failure. + */ +esp_err_t esp_rmaker_device_add_model(const esp_rmaker_device_t *device, const char *model); + /** Get device name from handle * * @param[in] device Device handle. diff --git a/components/esp_rainmaker/src/core/esp_rmaker_device.c b/components/esp_rainmaker/src/core/esp_rmaker_device.c index f7546cc..bf90ca4 100644 --- a/components/esp_rainmaker/src/core/esp_rmaker_device.c +++ b/components/esp_rainmaker/src/core/esp_rmaker_device.c @@ -45,6 +45,9 @@ esp_err_t esp_rmaker_device_delete(const esp_rmaker_device_t *device) if (_device->subtype) { free(_device->subtype); } + if (_device->model) { + free(_device->model); + } if (_device->name) { free(_device->name); } @@ -217,6 +220,26 @@ esp_err_t esp_rmaker_device_add_subtype(const esp_rmaker_device_t *device, const if ((_device->subtype = strdup(subtype)) != NULL ){ return ESP_OK; } else { + ESP_LOGE(TAG, "Failed to allocate memory for device subtype"); + return ESP_ERR_NO_MEM; + } +} + +/* Add a device model */ +esp_err_t esp_rmaker_device_add_model(const esp_rmaker_device_t *device, const char *model) +{ + if (!device || !model) { + ESP_LOGE(TAG, "Device handle or model cannot be NULL."); + return ESP_ERR_INVALID_ARG; + } + _esp_rmaker_device_t *_device = (_esp_rmaker_device_t *)device; + if (_device->model) { + free(_device->model); + } + if ((_device->model = strdup(model)) != NULL ){ + return ESP_OK; + } else { + ESP_LOGE(TAG, "Failed to allocate memory for device model"); return ESP_ERR_NO_MEM; } } diff --git a/components/esp_rainmaker/src/core/esp_rmaker_internal.h b/components/esp_rainmaker/src/core/esp_rmaker_internal.h index 1c888d3..b9d98d5 100644 --- a/components/esp_rainmaker/src/core/esp_rmaker_internal.h +++ b/components/esp_rainmaker/src/core/esp_rmaker_internal.h @@ -67,6 +67,7 @@ struct esp_rmaker_device { char *name; char *type; char *subtype; + char *model; esp_rmaker_device_write_cb_t write_cb; esp_rmaker_device_read_cb_t read_cb; void *priv_data; diff --git a/components/esp_rainmaker/src/core/esp_rmaker_node.c b/components/esp_rainmaker/src/core/esp_rmaker_node.c index 996c02c..018a9cb 100644 --- a/components/esp_rainmaker/src/core/esp_rmaker_node.c +++ b/components/esp_rainmaker/src/core/esp_rmaker_node.c @@ -38,6 +38,9 @@ static void esp_rmaker_node_info_free(esp_rmaker_node_info_t *info) if (info->fw_version) { free(info->fw_version); } + if (info->subtype) { + free(info->subtype); + } free(info); } } @@ -150,6 +153,7 @@ esp_err_t esp_rmaker_node_add_fw_version(const esp_rmaker_node_t *node, const ch info->fw_version = strdup(fw_version); if (!info->fw_version) { ESP_LOGE(TAG, "Failed to allocate memory for fw version."); + return ESP_ERR_NO_MEM; } return ESP_OK; } @@ -171,6 +175,29 @@ esp_err_t esp_rmaker_node_add_model(const esp_rmaker_node_t *node, const char *m info->model = strdup(model); if (!info->model) { ESP_LOGE(TAG, "Failed to allocate memory for node model."); + return ESP_ERR_NO_MEM; + } + return ESP_OK; +} + +esp_err_t esp_rmaker_node_add_subtype(const esp_rmaker_node_t *node, const char *subtype) +{ + if (!node || !subtype) { + ESP_LOGE(TAG, "Node handle or subtype cannot be NULL."); + return ESP_ERR_INVALID_ARG; + } + esp_rmaker_node_info_t *info = esp_rmaker_node_get_info(node); + if (!info) { + ESP_LOGE(TAG, "Failed to get Node Info."); + return ESP_ERR_INVALID_ARG; + } + if (info->subtype) { + free(info->subtype); + } + info->subtype = strdup(subtype); + if (!info->subtype) { + ESP_LOGE(TAG, "Failed to allocate memory for node subtype."); + return ESP_ERR_NO_MEM; } return ESP_OK; } diff --git a/components/esp_rainmaker/src/core/esp_rmaker_node_config.c b/components/esp_rainmaker/src/core/esp_rmaker_node_config.c index 3cd82c0..aa53ce3 100644 --- a/components/esp_rainmaker/src/core/esp_rmaker_node_config.c +++ b/components/esp_rainmaker/src/core/esp_rmaker_node_config.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include "esp_rmaker_internal.h" @@ -32,7 +33,13 @@ static esp_err_t esp_rmaker_report_info(json_gen_str_t *jptr) json_gen_obj_set_string(jptr, "name", info->name); json_gen_obj_set_string(jptr, "fw_version", info->fw_version); json_gen_obj_set_string(jptr, "type", info->type); + if (info->subtype) { + json_gen_obj_set_string(jptr, "subtype", info->subtype); + } json_gen_obj_set_string(jptr, "model", info->model); + const esp_app_desc_t *app_desc = esp_ota_get_app_description(); + json_gen_obj_set_string(jptr, "project_name", app_desc->project_name); + json_gen_obj_set_string(jptr, "platform", CONFIG_IDF_TARGET); json_gen_pop_object(jptr); return ESP_OK; } @@ -187,6 +194,9 @@ static esp_err_t esp_rmaker_report_devices_or_services(json_gen_str_t *jptr, cha if (device->subtype) { json_gen_obj_set_string(jptr, "subtype", device->subtype); } + if (device->model) { + json_gen_obj_set_string(jptr, "model", device->model); + } if (device->attributes) { json_gen_push_array(jptr, "attributes"); esp_rmaker_attr_t *attr = device->attributes;