Skip to content

Commit afcc67f

Browse files
committed
esp_rmaker_core: Add support for triggering phone app notifications
Supports two types of notifications 1. Parameter updates 2. Alerts Please check the API docs for more information
1 parent 2655228 commit afcc67f

File tree

3 files changed

+98
-8
lines changed

3 files changed

+98
-8
lines changed

components/esp_rainmaker/include/esp_rmaker_core.h

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ extern "C"
2424

2525
#define ESP_RMAKER_CONFIG_VERSION "2020-03-20"
2626

27-
#define MAX_VERSION_STRING_LEN 16
27+
/* Maximum length of the alert message that can be passed to esp_rmaker_raise_alert() */
28+
#define ESP_RMAKER_MAX_ALERT_LEN 100
2829

2930
/** @cond **/
3031
/** ESP RainMaker Event Base */
@@ -741,6 +742,46 @@ esp_err_t esp_rmaker_param_add_array_max_count(const esp_rmaker_param_t *param,
741742
*/
742743
esp_err_t esp_rmaker_param_update_and_report(const esp_rmaker_param_t *param, esp_rmaker_param_val_t val);
743744

745+
/** Update and notify a parameter
746+
*
747+
* Calling this API will update the parameter and report it to ESP RainMaker cloud similar to
748+
* esp_rmaker_param_update_and_report(). However, additionally, it will also trigger a notification
749+
* on the phone apps (if enabled).
750+
*
751+
* @note This should be used only when some local change requires explicit notification even when the
752+
* phone app is in background, not otherwise.
753+
* Eg. Alarm got triggered, temperature exceeded some threshold, etc.
754+
*
755+
* Alternatively, the esp_rmaker_raise_alert() API can also be used to trigger notification
756+
* on the phone apps with pre-formatted text.
757+
*
758+
* @param[in] param Parameter handle.
759+
* @param[in] val New value of the parameter.
760+
*
761+
* @return ESP_OK if the parameter was updated successfully.
762+
* @return error in case of failure.
763+
*/
764+
esp_err_t esp_rmaker_param_update_and_notify(const esp_rmaker_param_t *param, esp_rmaker_param_val_t val);
765+
766+
/** Trigger an alert on the phone app
767+
*
768+
* This API will trigger a notification alert on the phone apps (if enabled) using the formatted text
769+
* provided. Note that this does not send a notification directly to the phone, but reports the alert
770+
* to the ESP RainMaker cloud which then uses the Notification framework to send notifications to the
771+
* phone apps. The value does not get stored anywhere, nor is it linked to any node parameters.
772+
*
773+
* @note This should be used only if some event requires explicitly alerting the user even when the
774+
* phone app is in background, not otherwise.
775+
* Eg. "Motion Detected", "Fire alarm triggered"
776+
*
777+
* @param[in] alert_str NULL terminated pre-formatted alert string.
778+
* Maximum length can be ESP_RMAKER_MAX_ALERT_LEN, excluding NULL character.
779+
*
780+
* @return ESP_OK on success.
781+
* @return error in case of failure.
782+
*/
783+
esp_err_t esp_rmaker_raise_alert(const char *alert_str);
784+
744785
/** Get parameter name from handle
745786
*
746787
* @param[in] param Parameter handle.

components/esp_rainmaker/src/core/esp_rmaker_internal.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
#include <json_generator.h>
1919
#include <esp_rmaker_core.h>
2020

21-
#define RMAKER_PARAM_FLAG_VALUE_CHANGE 0x01
21+
#define RMAKER_PARAM_FLAG_VALUE_CHANGE (1 << 0)
22+
#define RMAKER_PARAM_FLAG_VALUE_NOTIFY (1 << 1)
2223
#define ESP_RMAKER_NVS_PART_NAME "nvs"
2324

2425
typedef enum {

components/esp_rainmaker/src/core/esp_rmaker_param.c

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,13 @@
3030
#define NODE_PARAMS_LOCAL_INIT_TOPIC_SUFFIX "params/local/init"
3131
#define NODE_PARAMS_REMOTE_TOPIC_SUFFIX "params/remote"
3232
#define TIME_SERIES_DATA_TOPIC_SUFFIX "params/ts_data"
33+
#define NODE_PARAMS_ALERT_TOPIC_SUFFIX "alert"
34+
35+
#define ESP_RMAKER_ALERT_KEY "esp.alert.str"
3336

3437
#define MAX_PUBLISH_TOPIC_LEN 64
35-
#define RMAKER_PARAMS_SIZE_MARGIN 50
38+
#define RMAKER_PARAMS_SIZE_MARGIN 50 /* To accommodate for changes in param values while creating JSON */
39+
#define RMAKER_ALERT_STR_MARGIN 25 /* To accommodate rest of the alert payload {"esp.alert.str":""} */
3640

3741
static size_t max_node_params_size = CONFIG_ESP_RMAKER_MAX_PARAM_DATA_SIZE;
3842
/* This buffer will be allocated once and will be reused for all param updates.
@@ -210,17 +214,25 @@ static esp_err_t esp_rmaker_allocate_and_populate_params(uint8_t flags, bool res
210214
return err;
211215
}
212216

213-
esp_err_t esp_rmaker_report_param_internal(void)
217+
static esp_err_t esp_rmaker_report_param_internal(uint8_t flags)
214218
{
215219
esp_err_t err = esp_rmaker_allocate_and_populate_params(RMAKER_PARAM_FLAG_VALUE_CHANGE, true);
216220
if (err == ESP_OK) {
217221
/* Just checking if there are indeed any params to report by comparing with a decent enough
218222
* length as even the smallest possible data, Eg. '{"d":{"p":0}}' will be > 10 bytes.
219223
*/
220224
if (strlen(node_params_buf) > 10) {
221-
snprintf(publish_topic, sizeof(publish_topic), "node/%s/%s",
222-
esp_rmaker_get_node_id(), NODE_PARAMS_LOCAL_TOPIC_SUFFIX);
223-
ESP_LOGI(TAG, "Reporting params: %s", node_params_buf);
225+
if (flags == RMAKER_PARAM_FLAG_VALUE_CHANGE) {
226+
snprintf(publish_topic, sizeof(publish_topic), "node/%s/%s",
227+
esp_rmaker_get_node_id(), NODE_PARAMS_LOCAL_TOPIC_SUFFIX);
228+
ESP_LOGI(TAG, "Reporting params: %s", node_params_buf);
229+
} else if (flags == RMAKER_PARAM_FLAG_VALUE_NOTIFY) {
230+
snprintf(publish_topic, sizeof(publish_topic), "node/%s/%s",
231+
esp_rmaker_get_node_id(), NODE_PARAMS_ALERT_TOPIC_SUFFIX);
232+
ESP_LOGI(TAG, "Notifying params: %s", node_params_buf);
233+
} else {
234+
return ESP_FAIL;
235+
}
224236
if (esp_rmaker_params_mqtt_init_done) {
225237
esp_rmaker_mqtt_publish(publish_topic, node_params_buf, strlen(node_params_buf), RMAKER_MQTT_QOS1, NULL);
226238
} else {
@@ -688,7 +700,21 @@ esp_err_t esp_rmaker_param_report(const esp_rmaker_param_t *param)
688700
return ESP_ERR_INVALID_ARG;
689701
}
690702
((_esp_rmaker_param_t *)param)->flags |= RMAKER_PARAM_FLAG_VALUE_CHANGE;
691-
return esp_rmaker_report_param_internal();
703+
return esp_rmaker_report_param_internal(RMAKER_PARAM_FLAG_VALUE_CHANGE);
704+
}
705+
706+
esp_err_t esp_rmaker_param_notify(const esp_rmaker_param_t *param)
707+
{
708+
if (!param) {
709+
ESP_LOGE(TAG, "Param handle cannot be NULL.");
710+
return ESP_ERR_INVALID_ARG;
711+
}
712+
((_esp_rmaker_param_t *)param)->flags |= (RMAKER_PARAM_FLAG_VALUE_CHANGE | RMAKER_PARAM_FLAG_VALUE_NOTIFY);
713+
esp_err_t err = esp_rmaker_report_param_internal(RMAKER_PARAM_FLAG_VALUE_NOTIFY);
714+
if (err != ESP_OK) {
715+
ESP_LOGW(TAG, "Failed to report parameter");
716+
}
717+
return esp_rmaker_report_param_internal(RMAKER_PARAM_FLAG_VALUE_CHANGE);
692718
}
693719

694720
esp_err_t esp_rmaker_param_update_and_report(const esp_rmaker_param_t *param, esp_rmaker_param_val_t val)
@@ -701,6 +727,16 @@ esp_err_t esp_rmaker_param_update_and_report(const esp_rmaker_param_t *param, es
701727
return err;
702728
}
703729

730+
esp_err_t esp_rmaker_param_update_and_notify(const esp_rmaker_param_t *param, esp_rmaker_param_val_t val)
731+
{
732+
esp_err_t err = esp_rmaker_param_update(param, val);
733+
/** Report parameter only if the RainMaker has started */
734+
if ((err == ESP_OK) && (esp_rmaker_get_state() == ESP_RMAKER_STATE_STARTED)) {
735+
err = esp_rmaker_param_notify(param);
736+
}
737+
return err;
738+
}
739+
704740
char *esp_rmaker_param_get_name(const esp_rmaker_param_t *param)
705741
{
706742
if (!param) {
@@ -718,3 +754,15 @@ char *esp_rmaker_param_get_type(const esp_rmaker_param_t *param)
718754
}
719755
return ((_esp_rmaker_param_t *)param)->type;
720756
}
757+
758+
esp_err_t esp_rmaker_raise_alert(const char *alert_str)
759+
{
760+
char msg[ESP_RMAKER_MAX_ALERT_LEN + 1]; /* + 1 for NULL terminattion */
761+
strlcpy(msg, alert_str, sizeof(msg));
762+
char buf[ESP_RMAKER_MAX_ALERT_LEN + RMAKER_ALERT_STR_MARGIN];
763+
snprintf(buf, sizeof(buf), "{\"%s\":\"%s\"}", ESP_RMAKER_ALERT_KEY, msg);
764+
snprintf(publish_topic, sizeof(publish_topic), "node/%s/%s",
765+
esp_rmaker_get_node_id(), NODE_PARAMS_ALERT_TOPIC_SUFFIX);
766+
ESP_LOGI(TAG, "Reporting alert: %s", buf);
767+
return esp_rmaker_mqtt_publish(publish_topic, buf, strlen(buf), RMAKER_MQTT_QOS1, NULL);
768+
}

0 commit comments

Comments
 (0)