Rainmaker configure Telegram API credentials externally without hard coding
-
- Posts: 8
- Joined: Sat Aug 26, 2023 6:43 am
Rainmaker configure Telegram API credentials externally without hard coding
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?
-
- Posts: 309
- Joined: Wed Feb 20, 2019 7:02 am
Re: Rainmaker configure Telegram API credentials externally without hard coding
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.
-
- Posts: 8
- Joined: Sat Aug 26, 2023 6:43 am
Re: Rainmaker configure Telegram API credentials externally without hard coding
@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.
-
- Posts: 8
- Joined: Sat Aug 26, 2023 6:43 am
Re: Rainmaker configure Telegram API credentials externally without hard coding
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:-
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);
}
-
- Posts: 309
- Joined: Wed Feb 20, 2019 7:02 am
Re: Rainmaker configure Telegram API credentials externally without hard coding
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"
-
- Posts: 8
- Joined: Sat Aug 26, 2023 6:43 am
Re: Rainmaker configure Telegram API credentials externally without hard coding
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?
-
- Posts: 309
- Joined: Wed Feb 20, 2019 7:02 am
Re: Rainmaker configure Telegram API credentials externally without hard coding
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.
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
Code: Select all
Param Token_param("Token", "custom.param.level", value(DEFAULT_NAME2), PROP_FLAG_READ | PROP_FLAG_WRITE | PROP_FLAG_PERSIST);
Who is online
Users browsing this forum: No registered users and 10 guests