Rainmaker configure Telegram API credentials externally without hard coding

cloudmiracle
Posts: 8
Joined: Sat Aug 26, 2023 6:43 am

Rainmaker configure Telegram API credentials externally without hard coding

Postby cloudmiracle » Thu Aug 31, 2023 7:16 pm

Have successfully configured Rainmaker on my ESP32 (Arduino), Android App and Telegram notifications by hard coding Telegram credentials in the code. I want to know if there is any way to enter the TelegramAPI credentials (chat_id and Token) without hardcoding it into the Arduino sketch? This is to enable the end-user to enter their own Telegram credentials over a browser interface for example or any other way so they can start getting notifications for the events. For example by use of Espressif softAP or BLE one can enter their WIFI credentials, in a similar fashion, is there a way to enter TelegramAPI credentials using an APP or something instead of hard coding on Arduino sketch or through Rainmaker platform?

ESP_Piyush
Posts: 263
Joined: Wed Feb 20, 2019 7:02 am

Re: Rainmaker configure Telegram API credentials externally without hard coding

Postby ESP_Piyush » Fri Sep 01, 2023 1:54 pm

The simplest way is to add custom string parameters to your device so that the app displays text boxes for them, wherein you can enter the credentials. You can check sample custom parameter usage here.

cloudmiracle
Posts: 8
Joined: Sat Aug 26, 2023 6:43 am

Re: Rainmaker configure Telegram API credentials externally without hard coding

Postby cloudmiracle » Sat Sep 02, 2023 6:02 am

@ESP_Piyush - Appreciate your reply and the hint. Was trying to understand the linked Custom Parameter Arduino example code, line 83 to 92 as against Rainmaker Standard Parameter Types link here: https://rainmaker.espressif.com/docs/st ... types.html. Not too familiar with Arduino coding but trying my best. Will give it a try and see if I can manage to get a text box displayed on the Android Rainmaker App and then callback write. A small code hint would help accelerate my coding.

cloudmiracle
Posts: 8
Joined: Sat Aug 26, 2023 6:43 am

Re: Rainmaker configure Telegram API credentials externally without hard coding

Postby cloudmiracle » Sat Sep 02, 2023 10:31 pm

Tried and managed to get the widget on the Android App but still have some issues:

1) Chat_ID normally is a nine digit number, is delivered to ESP32 successfully on the serial monitor but how do I save it as a variable to be able to use it for sending notification.
2) Token normally is a long string of 10 numbers followed by a colon and alphabets, for example 1234567890:abCdEfghiJkldKhjLmnefKfpeHKLdoewktl. The text space does not allocate such a long code nor does it appear as a string but again appears as a number on the serial monitor. Once again need to save it as a variable to be able to use it to send notifications.

Here is the code that I arrived at and tried giving me above shortfalls, perhaps something to do with a limit in number of characters that can be sent back and forth and format type of payload:-

Code: Select all

//This example demonstrates the ESP RainMaker with a custom device
#include "RMaker.h"
#include "WiFi.h"
#include "WiFiProv.h"

#define DEFAULT_POWER_MODE true
#define DEFAULT_NAME1 0
#define DEFAULT_NAME2 0

const char *service_name = "PROV_1234";
const char *pop = "abcd1234";

#define BOTtoken "Token"  //// your Bot Token (Get from Botfather)
#define CHAT_ID "Chat_ID"  ////
int Chat_ID; ////
const char *Token; ////

//GPIO for push button
#if CONFIG_IDF_TARGET_ESP32C3
static int gpio_0 = 9;
static int gpio_dimmer = 7;
#else
//GPIO for virtual device
static int gpio_0 = 0;
static int gpio_dimmer = 16;
#endif

bool dimmer_state = true;

// The framework provides some standard device types like switch, lightbulb, fan, temperature sensor.
// But, you can also define custom devices using the 'Device' base class object, as shown here
static Device *my_device = NULL;

void sysProvEvent(arduino_event_t *sys_event)
{
    switch (sys_event->event_id) {
    case ARDUINO_EVENT_PROV_START:
#if CONFIG_IDF_TARGET_ESP32S2
        Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on SoftAP\n", service_name, pop);
        printQR(service_name, pop, "softap");
#else
        Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on BLE\n", service_name, pop);
        printQR(service_name, pop, "ble");
#endif
        break;
    case ARDUINO_EVENT_PROV_INIT:
        wifi_prov_mgr_disable_auto_stop(10000);
        break;
    case ARDUINO_EVENT_PROV_CRED_SUCCESS:
        wifi_prov_mgr_stop_provisioning();
        break;
    default:;
    }
}

void write_callback(Device *device, Param *param, const param_val_t val, void *priv_data, write_ctx_t *ctx)
{
    const char *device_name = device->getDeviceName();
    const char *param_name = param->getParamName();

    if (strcmp(param_name, "Chat_ID") == 0) {
        Serial.printf("\nReceived value = %d for %s - %s\n", val.val.i, device_name, param_name);
        param->updateAndReport(val);
    }
     else if (strcmp(param_name, "Token") == 0) {
        Serial.printf("\nReceived value = %d for %s - %s\n", val.val.s, device_name, param_name);
        param->updateAndReport(val);
}
}

void setup()
{
    Serial.begin(115200);
    pinMode(gpio_0, INPUT);
    pinMode(gpio_dimmer, OUTPUT);
    digitalWrite(gpio_dimmer, DEFAULT_POWER_MODE);
    
    Node my_node;
    my_node = RMaker.initNode("ESP RainMaker Node");
    my_device = new Device("Telegram", "custom.device.other", &gpio_dimmer);
    if (!my_device) {
        return;
    }
    //Create custom dimmer device
    my_device->addNameParam();
    my_device->assignPrimaryParam(my_device->getParamByName(ESP_RMAKER_DEF_POWER_NAME));

    //Create and add a custom level parameter
    Param Chat_ID_param("Chat_ID", "custom.param.level", value(DEFAULT_NAME1), PROP_FLAG_READ | PROP_FLAG_WRITE);
    Chat_ID_param.addUIType(ESP_RMAKER_UI_TEXT);
    my_device->addParam(Chat_ID_param);
    
    Param Token_param("Token", "custom.param.level", value(DEFAULT_NAME2), PROP_FLAG_READ | PROP_FLAG_WRITE);
    Token_param.addUIType(ESP_RMAKER_UI_TEXT);
    my_device->addParam(Token_param);

    my_device->addCb(write_callback);
    
    //Add custom dimmer device to the node
    my_node.addDevice(*my_device);
    
    //This is optional
    RMaker.enableOTA(OTA_USING_TOPICS);
    //If you want to enable scheduling, set time zone for your region using setTimeZone().
    //The list of available values are provided here https://rainmaker.espressif.com/docs/time-service.html
    // RMaker.setTimeZone("Asia/Shanghai");
    // Alternatively, enable the Timezone service and let the phone apps set the appropriate timezone
    RMaker.enableTZService();

    RMaker.enableSchedule();

    RMaker.enableScenes();

    RMaker.start();

    WiFi.onEvent(sysProvEvent);
#if CONFIG_IDF_TARGET_ESP32S2
    WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name);
#else
    WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, pop, service_name);
#endif
}

void loop()
{
    if (digitalRead(gpio_0) == LOW) { //Push button pressed

        // Key debounce handling
        delay(100);
        int startTime = millis();
        while (digitalRead(gpio_0) == LOW) {
            delay(50);
        }
        int endTime = millis();

        if ((endTime - startTime) > 10000) {
            // If key pressed for more than 10secs, reset all
            Serial.printf("Reset to factory.\n");
            RMakerFactoryReset(2);
        } else if ((endTime - startTime) > 3000) {
            Serial.printf("Reset Wi-Fi.\n");
            // If key pressed for more than 3secs, but less than 10, reset Wi-Fi
            RMakerWiFiReset(2);
        } 
    }
    delay(100);
}

ESP_Piyush
Posts: 263
Joined: Wed Feb 20, 2019 7:02 am

Re: Rainmaker configure Telegram API credentials externally without hard coding

Postby ESP_Piyush » Mon Sep 04, 2023 11:01 am

I think your params are getting defined as numbers instead of strings. Probably, replacing the 0 with some placeholder string will work

Code: Select all

#define DEFAULT_NAME1 "Id"
#define DEFAULT_NAME2 "Token"

cloudmiracle
Posts: 8
Joined: Sat Aug 26, 2023 6:43 am

Re: Rainmaker configure Telegram API credentials externally without hard coding

Postby cloudmiracle » Sat Sep 09, 2023 4:13 am

Yes I managed to get the "string" issue corrected. Great. The issue of storing chat_id and token in to the retentive memory (power cycle) still remains, it seems SPIFFS do not allow storing data while under Rainmaker partition scheme, the code stops working completely, or may be I am not doing it correctly. Any suggestions?

ESP_Piyush
Posts: 263
Joined: Wed Feb 20, 2019 7:02 am

Re: Rainmaker configure Telegram API credentials externally without hard coding

Postby ESP_Piyush » Wed Sep 20, 2023 7:27 pm

Just pass PROP_FLAG_PERSIST in addition to PROP_FLAG_READ to PROP_FLAG_WRITE while creating your parameter so that it also gets stored in the persistent memory. Eg.

Code: Select all

    Param Token_param("Token", "custom.param.level", value(DEFAULT_NAME2), PROP_FLAG_READ | PROP_FLAG_WRITE | PROP_FLAG_PERSIST);
On a bootup, when you add the params in your service, your callback will be invoked with the stored values with ctx->src set to ESP_RMAKER_REQ_SRC_INIT

Who is online

Users browsing this forum: No registered users and 68 guests